6.1 Gateway 的角色:消息中枢
WebSocket Gateway 是 OpenClaw 的消息中枢,负责:
- 维护平台连接:管理 WhatsApp、Telegram、Discord 等渠道的长连接
- 客户端通信:为 UI 客户端、CLI、远程节点提供 WebSocket API
- 会话管理:维护多渠道、多用户的会话状态
- 认证授权:验证客户端身份,控制访问权限
objectivec
┌─────────────────────────────────────────────────────────────┐
│ WebSocket Gateway │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │WhatsApp │ │Telegram │ │Discord │ │ 微信 │ ... │
│ │ Provider│ │ Provider│ │ Provider│ │ Provider│ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ └────────────┴─────┬──────┴────────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Router │ 消息路由 │
│ └─────┬─────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ │ │ │ │
│ ┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐ │
│ │ CLI │ │ WebChat │ │ macOS App │ ... │
│ └─────────┘ └───────────┘ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
6.2 协议设计
消息帧格式
所有 WebSocket 通信使用 JSON 格式,分为三种帧类型:
typescript
// 请求帧
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; // 序列号(可选)
}
示例交互
arduino
Client Gateway
│ │
│──── req:connect ──────────────>│ 首帧必须是 connect
│<──── res (ok) ─────────────────│ 或 res error + close
│ │
│<──── event:tick ───────────────│ 心跳
│<──── event:presence ───────────│ 状态同步
│ │
│──── req:agent ────────────────>│ 发起 AI 请求
│<──── res:agent ────────────────│ 确认接受
│<──── event:agent ──────────────│ 流式输出
│<──── res:agent ────────────────│ 完成
│ │
6.3 连接生命周期
1. 连接建立
客户端连接 Gateway 时,首帧必须是 connect 请求:
json
{
"type": "req",
"id": "conn_001",
"method": "connect",
"params": {
"token": "your-gateway-token",
"clientId": "my-client",
"version": "1.0.0"
}
}
2. 认证
Gateway 验证 token:
json
// 成功
{
"type": "res",
"id": "conn_001",
"ok": true,
"payload": {
"serverVersion": "1.2.3",
"agents": ["main"]
}
}
// 失败
{
"type": "res",
"id": "conn_001",
"ok": false,
"error": "Invalid token"
}
3. 心跳
Gateway 定期发送 tick 事件:
json
{
"type": "event",
"event": "tick",
"payload": {
"ts": 1704067200000
}
}
4. 断开连接
客户端或服务器可以随时关闭连接。Gateway 会:
- 清理会话状态
- 通知其他客户端(如果需要)
- 释放资源
6.4 认证与授权
Token 认证
Gateway 使用 token 进行认证:
json5
{
gateway: {
token: "your-secret-token", // 或从环境变量读取
}
}
bash
# 环境变量
OPENCLAW_GATEWAY_TOKEN=your-secret-token
设备配对
远程节点需要先配对:
bash
# 生成配对码
openclaw pair generate
# 输出
Pairing code: ABCD-EFGH
Expires in: 5 minutes
客户端使用配对码连接:
json
{
"type": "req",
"method": "connect",
"params": {
"pairCode": "ABCD-EFGH"
}
}
6.5 常用 RPC 方法
agent
调用 Agent 进行推理:
json
{
"type": "req",
"id": "agent_001",
"method": "agent",
"params": {
"sessionKey": "agent:main:main",
"message": "帮我整理文件",
"model": "claude-3-5-sonnet"
}
}
send
发送消息到渠道:
json
{
"type": "req",
"id": "send_001",
"method": "send",
"params": {
"channel": "telegram",
"target": "123456789",
"message": {
"text": "你好!"
}
}
}
health
健康检查:
json
{
"type": "req",
"id": "health_001",
"method": "health",
"params": {}
}
status
获取状态:
json
{
"type": "req",
"id": "status_001",
"method": "status",
"params": {}
}
6.6 常用事件
tick
心跳事件,定期发送。
agent
Agent 状态变更:
json
{
"type": "event",
"event": "agent",
"payload": {
"stream": "assistant",
"delta": "你好!有什么可以帮你的?"
}
}
presence
用户在线状态变更:
json
{
"type": "event",
"event": "presence",
"payload": {
"channel": "whatsapp",
"userId": "123456789",
"status": "online"
}
}
chat
收到新消息:
json
{
"type": "event",
"event": "chat",
"payload": {
"channel": "telegram",
"sender": {
"id": "123456789",
"name": "Alice"
},
"message": {
"text": "你好"
}
}
}
shutdown
Gateway 即将关闭:
json
{
"type": "event",
"event": "shutdown",
"payload": {
"reason": "maintenance",
"gracePeriodMs": 30000
}
}
6.7 连接管理
多客户端
Gateway 支持多个客户端同时连接:
markdown
┌─────────────┐
│ Gateway │
└──────┬──────┘
│
┌────┼────┬────────┐
│ │ │ │
▼ ▼ ▼ ▼
CLI Web macOS iOS App
竞争处理
当多个客户端同时操作同一会话时:
- 请求排队:请求按到达顺序处理
- 状态同步:变更通过事件广播给所有客户端
- 乐观锁:某些操作使用版本号防止冲突
6.8 Gateway 配置
基本配置
json5
{
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"
}
}
}
安全配置
json5
{
gateway: {
// 只允许可信来源
cors: {
origins: ["https://your-app.example.com"]
},
// 速率限制
rateLimit: {
windowMs: 60000,
maxRequests: 100
},
// 连接超时
connectionTimeout: 300000, // 5 分钟
}
}
6.9 客户端实现示例
JavaScript/TypeScript
typescript
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 的核心枢纽:
| 组件 | 职责 |
|---|---|
| 连接管理 | 维护客户端和渠道连接 |
| 协议处理 | 解析和生成消息帧 |
| 认证授权 | 验证身份,控制权限 |
| 消息路由 | 将消息分发到正确的目标 |
| 状态同步 | 广播状态变更给客户端 |
| 会话管理 | 维护会话状态和持久化 |
🦞 下一章预告:我们将深入 Skills 技能系统,了解如何扩展 Agent 的能力。