Appearance
WebSocket 连接与认证
系统提供三个 WebSocket 端点用于实时通信。
端点列表
| 端点 | URL | 用途 |
|---|---|---|
| 对话 WS | ws://host/api/v1/conversations/{id}/ws?token=xxx | 单对话实时交互 |
| 项目 WS | ws://host/api/v1/projects/{id}/ws?token=xxx | 画布 + 对话融合 |
| 画布 WS | ws://host/api/v1/canvas/{id}/ws?token=xxx | 纯画布编辑 |
连接流程
认证方式
JWT Token 通过 URL 查询参数传递:
ws://host/api/v1/conversations/{conversation_id}/ws?token=eyJhbGci...注意
Token 不能通过 WebSocket 消息或 HTTP Header 传递,必须通过查询参数。
资源锁定
每个资源(对话/项目/画布)同一时间只允许一个 WebSocket 连接:
- 连接成功后自动获取锁
- 断开连接后自动释放锁
- 尝试连接已锁定的资源会收到 Close Code
4009
WebSocket Close Codes
| Code | 含义 |
|---|---|
1000 | 正常关闭 |
1001 | 服务端关闭(如服务重启) |
4001 | 认证失败(Token 无效或过期) |
4008 | 用户被踢出 |
4009 | 资源冲突(已有连接占用或锁丢失) |
消息格式
所有 WebSocket 消息均为 JSON 文本帧。
客户端 → 服务端
对话 WebSocket 使用信封格式:
json
{
"type": "append_message",
"payload": { ... },
"request_id": "可选的请求关联ID"
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 消息类型 |
payload | object | 是 | 消息内容(结构随类型变化) |
request_id | string | 否 | 客户端生成的 UUID,服务端会在相关响应中回传 |
服务端 → 客户端
服务端消息不使用信封,直接是消息体:
json
{
"type": "llm_text_chunk",
"chunk": "Hello",
"request_id": "从客户端请求继承"
}断线重连
- 重新建立 WebSocket 连接到同一资源
- 服务端会自动推送断线期间缓存的消息(流式 chunk 缓冲)
- 完整消息历史可通过 REST API 获取
- 缓冲消息有 TTL 限制,超时后不再可用
消息大小限制
单条 WebSocket 消息最大 2 MB。超过此限制的消息会被拒绝。
心跳
WebSocket 层面使用标准的 Ping/Pong 帧保持连接活跃,客户端无需手动处理。