Files
crank/docs/protocols/websocket.md
T
2026-04-06 01:57:26 +03:00

134 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WebSocket
## 1. Роль протокола в проекте
WebSocket поддерживается как полноценный upstream protocol для realtime, push-oriented и stateful integrations. Он не заменяет downstream MCP transport, а работает за Crank proxy.
Иными словами:
- downstream: MCP `Streamable HTTP`;
- upstream: WebSocket;
- Crank нормализует WebSocket lifecycle в bounded MCP tool semantics.
## 2. Что поддерживается в целевом продукте
- клиентское WebSocket подключение к внешнему upstream;
- custom headers и auth profiles;
- handshake config;
- optional subprotocol selection;
- subscription payload или start message;
- bounded `window` mode;
- `session` mode с `start/poll/stop`;
- `async_job` mode для control-plane и progress channels;
- JSON message parsing;
- text-frame based event collection;
- mapping `MCP input -> subscribe payload`;
- mapping `WebSocket message -> normalized JSON`;
- heartbeat/keepalive config;
- reconnect policy для controlled session modes.
## 3. Что не входит в текущий продуктовый scope
- raw binary frame passthrough в LLM;
- arbitrary bidirectional conversation tunnel;
- full message bus semantics;
- generic browser-like socket inspector;
- guaranteed resumability across arbitrary upstream websocket providers.
## 4. Ключевое архитектурное ограничение
WebSocket не публикуется как "живой канал в чат". Он должен быть выражен в одной из execution models:
- `window`
- `session`
- `async_job`
Недопустимо:
- бесконечно проксировать frames напрямую в MCP client;
- скрывать жизненный цикл сокета за одним неопределенным tool call;
- смешивать downstream SSE transport и upstream WebSocket semantics в одну абстракцию.
## 5. Типовые use cases
### 5.1. Monitoring and telemetry
- realtime метрики;
- device telemetry;
- market data;
- anomaly events.
### 5.2. Event subscriptions
- alert streams;
- queue events;
- workflow transitions;
- security events.
### 5.3. Stateful control channels
- rollout progress;
- remote task status;
- infrastructure control plane updates;
- long-running remote sessions.
## 6. Внутренняя модель WebSocket operation
WebSocket operation должна включать:
- `url`
- `headers`
- `subprotocols`
- `connect_timeout_ms`
- `heartbeat_interval_ms`
- `subscribe_message_template`
- `unsubscribe_message_template`
- `input_mapping`
- `output_mapping`
- `execution_config`
- `tool_description`
## 7. Как оператор настраивает WebSocket operation
1. Указывает URL WebSocket upstream.
2. При необходимости выбирает auth profile и headers.
3. Указывает subprotocol или оставляет пустым.
4. Выбирает execution mode: `window`, `session` или `async_job`.
5. Настраивает subscribe payload.
6. Указывает правила извлечения items, status и cursor.
7. Настраивает aggregation limits.
8. Выполняет test run.
9. Публикует operation как MCP tool или tool family.
## 8. Поведение runtime
При выполнении WebSocket operation runtime должен:
1. Валидировать MCP input.
2. Построить subscribe payload.
3. Открыть WebSocket connection.
4. Пройти handshake и auth.
5. Отправить subscribe message.
6. Собрать bounded window или session step.
7. Нормализовать messages в JSON.
8. Применить output mapping.
9. Закрыть соединение или сохранить session state.
## 9. Критические нюансы
- upstream WebSocket может быть stateful и требовать explicit unsubscribe;
- heartbeat и reconnect должны быть управляемыми через config, а не захардкоженными;
- session state должен хранить cursor, last_event и subscription metadata;
- disconnect downstream MCP client не означает cancel upstream session;
- runtime обязан уметь cleanly завершать orphaned connections.
## 10. Почему WebSocket должен быть отдельным adapter
WebSocket нельзя свести к "почти SSE" или "почти HTTP", потому что:
- transport двунаправленный;
- lifecycle connection stateful;
- есть handshake, heartbeat и reconnect;
- подписка часто задается сообщением, а не URL;
- semantics событий и прогресса отличаются от request-response вызова.