通过多路复用 WebSocket 进行流式传输
单个 WebSocket 承载聊天、通知、偏好设置、充提监控、工作流和 Data Studio 预览,并支持逐频道序列号与断线重放。
GET /v1/stream (WebSocket)
网关的所有长连接服务端推送流都复用同一个 WebSocket。这样可以避免占满浏览器每个来源约六条 HTTP/1.1 连接的限制,也不会因某个标签页中的繁忙或阻塞流影响其他普通请求。
| 方法 | GET (HTTP Upgrade: websocket) |
| 路径 | /v1/stream |
| 认证 | ?token=<GATEWAY_AUTH_TOKEN> |
连接
连接 /v1/stream,并根据网关来源使用 ws:// 或 wss://。启用 GATEWAY_AUTH_TOKEN 时追加 ?token=<token>;错误或缺失的 token 会在握手时以 401 拒绝。频道表示流类型,键用于限定频道内的一项订阅。
wss://<gateway-host>/v1/stream?token=<GATEWAY_AUTH_TOKEN>频道
| Channel | Key | Replay | Source |
|---|---|---|---|
chat | session_id | yes | POST /v1/chat/stream |
notifications | "" | no | notification bus |
prefs | "" | no | runtime preferences |
deposit | chain:asset:address | yes | deposit watch |
withdraw | operationId | yes | withdraw watch |
workflow | instanceId | yes | workflow run bus |
data-studio | session_id | yes | Data Studio preview |
chat、deposit、withdraw、workflow 与 data-studio 支持重放;notifications 与 prefs 只发送订阅后产生的实时事件。按需频道会在首个订阅者加入时启动上游,并在最后一个订阅者离开时停止。
客户端到服务端帧
发送 JSON 控制帧来订阅或取消订阅。同一 (channel, key) 的再次订阅会替换旧连接。fromSeq 是重连游标;服务端只重放序列号严格大于它的缓冲事件。
{ "op": "subscribe", "channel": "chat", "key": "chat_abc", "fromSeq": 0 }{ "op": "unsubscribe", "channel": "chat", "key": "chat_abc" }服务端到客户端帧
每个事件都是一个 JSON 帧。seq 在每个 (channel, key) 内从 1 单调递增,type 与 data 保留频道事件的原始结构。
{ "channel": "chat", "key": "chat_abc", "seq": 12, "type": "text_delta", "data": { "text": "…" }控制帧
__error 表示订阅被拒绝或没有实时流;__truncated 表示重放缓冲区已溢出并丢弃更早事件。这两种帧的 seq 都为 0,不参与重放。
重连与恢复
断线后,参考客户端使用指数退避重连,并从每个频道已见过的最高 seq 恢复。缓冲区只存在于当前进程,网关重启后不会保留。重试预算耗尽时,每个实时订阅的错误处理器会触发一次,同时客户端仍按封顶退避继续尝试。
保活
网关会按固定间隔向每个打开的套接字发送 ping。浏览器会自动 pong,从而避免代理关闭空闲连接,包括当前没有活动订阅的连接。