WebChat WebSocket 链路
全链路流程
浏览器 (app.sayclaw.ai/portal/chat/)
│
│ 1. POST /api/v1/me/webchat/session/create
│ body: { instance_id: "oc-ai-jp-2-02" }
│ → 返回 { ws_url, session_key, token }
│
│ 2. WebSocket 连接
│ wss://api.sayclaw.ai/oc-ws/oc-ai-jp-2-02?token=xxx
│
▼
Nginx (小龙 443)
│
│ 3. auth_request → portal-api /internal/webchat/verify?token=xxx
│ ← 返回 200 + X-User-ID + X-Instance-ID + X-Session-Key
│
│ 4. map $oc_instance_id → $oc_backend (oc-ws-map.conf)
│ 例: oc-ai-jp-2-02 → 34.85.76.114:18810
│
│ 5. proxy_pass + Upgrade: websocket
│ + 透传 X-User-ID / X-Instance-ID / X-Session-Key
│
▼
OC Gateway (小二/小三,trusted-proxy 模式)
│
│ 6. 验证 trusted-proxy 头部
│ 接受 X-User-ID 作为用户身份
│
│ 7. 创建/恢复 agent session
│ 调用 LLM (通过 One API/One-API)
│
│ 8. 流式回复 → WebSocket → 浏览器
│
▼
LLM (Claude / GPT / Gemini)
关键配置点
1. Portal Chat 页面
URL 格式:/portal/chat/?instance_id=oc-ai-jp-2-02&name=实例名&model=claude-sonnet-4-6
instance_id必须从 URL query param 传入,否则报 "instance_id 不能为空"- 登录态通过
localStorage.sc_portal_token传递
2. portal-api 鉴权接口
POST /api/v1/me/webchat/session/create
- 验证 JWT token
- 验证用户有权限访问该 instance_id
- 返回 WS 连接所需的 token 和 session_key
GET /api/v1/internal/webchat/verify?token=xxx(Nginx auth_request 调用)
- 验证 token 有效性
- 必须返回响应头:
X-User-IDX-Instance-IDX-Session-Key
3. Nginx 配置
oc-ws-map.conf:instance_id → backend 映射auth_request:调用 portal-api 验证proxy_pass http://$oc_backend/:动态路由到实例 Gatewayproxy_read_timeout 86400:WS 长连接保持 24 小时
4. OC Gateway 配置
必须为 trusted-proxy 模式:
{
"gateway": {
"auth": {
"mode": "trusted-proxy",
"trustedProxy": { "userHeader": "X-User-ID" }
},
"trustedProxies": ["35.243.76.69"],
"controlUi": {
"allowedOrigins": ["https://app.sayclaw.ai", "https://m.sayclaw.ai"],
"dangerouslyDisableDeviceAuth": true
}
}
}
故障排查
| 症状 | 原因 | 解决 |
|---|---|---|
| "instance_id 不能为空" | Chat URL 缺少 ?instance_id=xxx | 从工作台点击进入,或手动加参数 |
| "连接中..." 一直转 | WS 握手失败 | 检查 Nginx error.log、Gateway 是否运行 |
| "device identity required" | Gateway 不是 trusted-proxy 模式 | 修改 openclaw.json auth.mode |
| 连上但不回复 | agents.defaults.model 为空 | 检查 openclaw.json 模型配置 |
| 403 from verify | token 过期或 instance 无权限 | 重新登录,检查 user_instances 表 |