意项
39.91M · 2026-03-23
WebSocket Gateway 是 OpenClaw 的消息中枢,负责:
┌─────────────────────────────────────────────────────────────┐
│ WebSocket Gateway │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │WhatsApp │ │T@elegrimm │ │Discord │ │ 微信 │ ... │
│ │ Provider│ │ Provider│ │ Provider│ │ Provider│ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ └────────────┴─────┬──────┴────────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Router │ 消息路由 │
│ └─────┬─────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ │ │ │ │
│ ┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐ │
│ │ CLI │ │ WebChat │ │ macOS App │ ... │
│ └─────────┘ └───────────┘ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
所有 WebSocket 通信使用 JSON 格式,分为三种帧类型:
// 请求帧
interface Request {
type: "req";
id: string; // 唯一标识,用于匹配响应
method: string; // 方法名
params: object; // 参数
}
// 响应帧
interface Response {
type: "res";
id: string; // 对应请求的 id
ok: boolean; // 是否成功
payload?: object; // 成功时的数据
error?: string; // 失败时的错误信息
}
// 事件帧
interface Event {
type: "event";
event: string; // 事件名
payload: object; // 事件数据
seq?: number; // 序列号(可选)
}
Client Gateway
│ │
│──── req:connect ──────────────>│ 首帧必须是 connect
│<──── res (ok) ─────────────────│ 或 res error + close
│ │
│<──── event:tick ───────────────│ 心跳
│<──── event:presence ───────────│ 状态同步
│ │
│──── req:agent ────────────────>│ 发起 AI 请求
│<──── res:agent ────────────────│ 确认接受
│<──── event:agent ──────────────│ 流式输出
│<──── res:agent ────────────────│ 完成
│ │
客户端连接 Gateway 时,首帧必须是 connect 请求:
{
"type": "req",
"id": "conn_001",
"method": "connect",
"params": {
"token": "your-gateway-token",
"clientId": "my-client",
"version": "1.0.0"
}
}
Gateway 验证 token:
// 成功
{
"type": "res",
"id": "conn_001",
"ok": true,
"payload": {
"serverVersion": "1.2.3",
"agents": ["main"]
}
}
// 失败
{
"type": "res",
"id": "conn_001",
"ok": false,
"error": "Invalid token"
}
Gateway 定期发送 tick 事件:
{
"type": "event",
"event": "tick",
"payload": {
"ts": 1704067200000
}
}
客户端或服务器可以随时关闭连接。Gateway 会:
Gateway 使用 token 进行认证:
{
gateway: {
token: "your-secret-token", // 或从环境变量读取
}
}
# 环境变量
OPENCLAW_GATEWAY_TOKEN=your-secret-token
远程节点需要先配对:
# 生成配对码
openclaw pair generate
# 输出
Pairing code: ABCD-EFGH
Expires in: 5 minutes
客户端使用配对码连接:
{
"type": "req",
"method": "connect",
"params": {
"pairCode": "ABCD-EFGH"
}
}
调用 Agent 进行推理:
{
"type": "req",
"id": "agent_001",
"method": "agent",
"params": {
"sessionKey": "agent:main:main",
"message": "帮我整理文件",
"model": "claude-3-5-sonnet"
}
}
发送消息到渠道:
{
"type": "req",
"id": "send_001",
"method": "send",
"params": {
"channel": "telegram",
"target": "123456789",
"message": {
"text": "你好!"
}
}
}
健康检查:
{
"type": "req",
"id": "health_001",
"method": "health",
"params": {}
}
获取状态:
{
"type": "req",
"id": "status_001",
"method": "status",
"params": {}
}
心跳事件,定期发送。
Agent 状态变更:
{
"type": "event",
"event": "agent",
"payload": {
"stream": "assistant",
"delta": "你好!有什么可以帮你的?"
}
}
用户在线状态变更:
{
"type": "event",
"event": "presence",
"payload": {
"channel": "whatsapp",
"userId": "123456789",
"status": "online"
}
}
收到新消息:
{
"type": "event",
"event": "ch@t",
"payload": {
"channel": "telegram",
"sender": {
"id": "123456789",
"name": "Alice"
},
"message": {
"text": "你好"
}
}
}
Gateway 即将关闭:
{
"type": "event",
"event": "shutdown",
"payload": {
"reason": "maintenance",
"gracePeriodMs": 30000
}
}
Gateway 支持多个客户端同时连接:
┌─────────────┐
│ Gateway │
└──────┬──────┘
│
┌────┼────┬────────┐
│ │ │ │
▼ ▼ ▼ ▼
CLI Web macOS iOS App
当多个客户端同时操作同一会话时:
{
gateway: {
// 地址
bind: "loopback", // 只本地
// bind: "0.0.0.0", // 所有接口
port: 19000,
// 认证
token: "your-token",
// 远程访问
remote: {
enabled: true,
url: "https://your-gateway.example.com"
},
// Tailscale
tailscale: {
enabled: true,
hostname: "openclaw-gateway"
}
}
}
{
gateway: {
// 只允许可信来源
cors: {
origins: ["https://your-app.example.com"]
},
// 速率限制
rateLimit: {
windowMs: 60000,
maxRequests: 100
},
// 连接超时
connectionTimeout: 300000, // 5 分钟
}
}
import WebSocket from 'ws';
const ws = new WebSocket('ws://localhost:19000');
ws.on('open', () => {
// 发送连接请求
ws.send(JSON.stringify({
type: 'req',
id: 'conn_001',
method: 'connect',
params: { token: 'your-token' }
}));
});
ws.on('message', (data) => {
const frame = JSON.parse(data.toString());
if (frame.type === 'res') {
console.log('Response:', frame);
} else if (frame.type === 'event') {
console.log('Event:', frame.event, frame.payload);
}
});
// 调用 Agent
function callAgent(message: string) {
ws.send(JSON.stringify({
type: 'req',
id: `agent_${Date.now()}`,
method: 'agent',
params: {
sessionKey: 'agent:main:main',
message
}
}));
}
WebSocket Gateway 是 OpenClaw 的核心枢纽:
| 组件 | 职责 |
|---|---|
| 连接管理 | 维护客户端和渠道连接 |
| 协议处理 | 解析和生成消息帧 |
| 认证授权 | 验证身份,控制权限 |
| 消息路由 | 将消息分发到正确的目标 |
| 状态同步 | 广播状态变更给客户端 |
| 会话管理 | 维护会话状态和持久化 |