跳到主要内容

Web 端 WebSocket 直连 OpenClaw Gateway 架构

为了让 app.sayclaw.ai (Web 端) 拥有和 Telegram 机器人完全一致的 OpenClaw 能力(工具调用、长期记忆、终端执行等),废弃前端直连 LLM API 的旧方案,改为前端通过 WebSocket 直连内网 OpenClaw Gateway

1. 核心交互时序

[前端 Web]                 [Portal API]                  [OpenClaw Gateway]
│ │ │
│ 1. POST /webchat/session │ │
│ 携带当前用户 Token │ │
├──────────────────────────►│ │
│ │ 2. 校验权限,换取 Gateway Token │
│ │生成短效 Ephemeral Token (JWT) │
│ 3. 返回 ws_url & token │ │
◄───────────────────────────┤ │
│ │ │
│ 4. WSS 连接建立 (带token) │ │
├───────────────────────────┼──────────────────────────────►│
│ │ │ 5. 校验 Token,建立连接
│ 6. 发送聊天消息 (JSON) │ │
├───────────────────────────┼──────────────────────────────►│
│ │ │ 7. OpenClaw 处理 & 调工具
│ 8. 流式返回状态与结果 │ │
◄───────────────────────────┼───────────────────────────────┤

2. Portal API 接口定义

2.1 申请 WebSocket 会话凭证

  • 路由: POST /api/v1/webchat/session
  • 鉴权: 需员工登录 Token (Bearer)
  • 请求参数:
{
"instance_id": "oc-xxx-yyy", // 员工要对话的 AI 实例 ID
"session_key": "web_default" // 可选,会话隔离标识
}
  • 响应数据:
{
"code": 0,
"data": {
"ws_url": "wss://api.sayclaw.ai/oc-ws/oc-xxx-yyy",
"ephemeral_token": "eyJhbGciOiJIUzI1Ni...短效5分钟",
"expires_in": 300
}
}

3. 前端 WebSocket 消息协议

连接建立后,前端与 Gateway 之间的纯 JSON 文本协议。

3.1 前端发送消息 (Client -> Gateway)

{
"type": "message",
"data": {
"text": "帮我查一下昨天注册的用户数",
"attachments": []
}
}

3.2 Gateway 流式返回 (Gateway -> Client)

前端需根据 type 渲染 UI(类似 ChatGPT 的思考过程和最终回复)。

1. 状态更新 (思考中/调工具)

{
"type": "status",
"data": {
"state": "working",
"text": "正在查询数据库..."
}
}

2. 文本块增量 (打字机效果)

{
"type": "chunk",
"data": {
"text": "昨天共有 "
}
}

3. 最终完成消息

{
"type": "done",
"data": {
"full_text": "昨天共有 150 名新注册用户。",
"usage": {
"total_tokens": 120
}
}
}

4. 基础设施配置 (Nginx 反向代理)

为了避免暴露内网的 OpenClaw 真实端口,在网关层 (Nginx 或 Cloudflare) 统一做一个 WSS 路由转发。

Nginx 配置模板

server {
listen 443 ssl;
server_name api.sayclaw.ai;

# ... SSL 配置省略 ...

# 路由约定:/oc-ws/{instance_id} 转发到内部 OpenClaw 的 WS 端口
# 假设 OpenClaw Gateway 跑在内网 10.0.0.5:8080
location ~ ^/oc-ws/(.*)$ {
# 使用 URL 重写去掉 /oc-ws 前缀
rewrite ^/oc-ws/(.*)$ /ws/$1 break;

proxy_pass http://10.0.0.5:8080;

# 开启 WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;

# 传递真实 IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_addrs;

# WS 长连接超时设置
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}