网关架构
概述¶
- 单个长期存活的 Gateway 拥有所有消息界面(WhatsApp 通过 Baileys,Telegram 通过 grammY,Slack、Discord、Signal、iMessage、WebChat)。
- 控制平面客户端(macOS 应用、CLI、Web UI、自动化)通过 WebSocket 连接到
配置绑定主机上的 Gateway(默认
127.0.0.1:18789)。 - Nodes(macOS/iOS/Android/headless)也通过 WebSocket 连接,但
声明
role: node并带有显式 caps/commands。 - 每个主机一个 Gateway。它是唯一打开 WhatsApp 会话的地方。
- 托管 widget 界面 由 Gateway HTTP 服务器在以下路径下提供:
/__openclaw__/canvas/(托管 widget 文档)/__openclaw__/a2ui/(A2UI 渲染器资源)
它使用与 Gateway 相同的端口(默认 18789)。
组件与流程¶
Gateway(守护进程)¶
- 维护提供商连接。
- 暴露类型化 WS API(请求、响应、服务器推送事件)。
- 根据 JSON Schema 验证入站帧。
- 发出诸如
agent、chat、presence、health、heartbeat、cron等事件。
客户端(mac 应用 / CLI / Web 管理)¶
- 每个客户端一个 WS 连接。
- 发送请求(
health、status、send、agent、system-presence)。 - 订阅事件(
tick、agent、presence、shutdown)。
Nodes(macOS / iOS / Android / headless)¶
- 以
role: node连接到 同一个 WS 服务器。 - 在
connect中提供设备身份。配对是 基于设备 的(角色node),并且 审批保存在设备配对存储中。 - 暴露诸如
camera.*、screen.record和location.get等命令。 macOS 应用还暴露canvas.*下的 widget 面板命令。
协议详情:Gateway 协议
WebChat¶
- 使用 Gateway WS API 处理聊天历史和发送的静态 UI。
- 在远程设置中,通过与其他客户端相同的 SSH/Tailscale 隧道连接。
连接生命周期(单个客户端)¶
sequenceDiagram
participant Client
participant Gateway
Client->>Gateway: req:connect
Gateway-->>Client: res (ok)
Note right of Gateway: or res error + close
Note left of Client: payload=hello-ok<br>snapshot: presence + health
Gateway-->>Client: event:presence
Gateway-->>Client: event:tick
Client->>Gateway: req:agent
Gateway-->>Client: res:agent<br>ack {runId, status:"accepted"}
Gateway-->>Client: event:agent<br>(streaming)
Gateway-->>Client: res:agent<br>final {runId, status, summary}
线路协议(摘要)¶
- 传输:WebSocket,文本帧,JSON 负载。
- 第一个帧 必须 是
connect。 - 握手后:
- 请求:
{type:"req", id, method, params}→{type:"res", id, ok, payload|error} - 事件:
{type:"event", event, payload, seq?, stateVersion?} hello-ok.features.methods/events是发现元数据,而不是 每个可调用 helper 路由的生成转储。- 共享密钥认证接受配置的秘密,位于
connect.params.auth.token或connect.params.auth.password。gateway.auth.mode选择配置的值(gateway.auth.token或gateway.auth.password),而不是必需的线路字段。 - 携带身份的模式,例如 Tailscale Serve
(
gateway.auth.allowTailscale: true)或非回环gateway.auth.mode: "trusted-proxy",从请求头而不是connect.params.auth.*满足认证。 - 私有入口
gateway.auth.mode: "none"完全禁用共享密钥认证。 请勿在公共或不受信任的入口上启用该模式。 - 具有副作用的方法(
send、agent)需要幂等键,以便安全重试。服务器保留短期去重缓存。 - Nodes 必须在
connect中包含role: "node"以及 caps/commands/permissions。
配对与本地信任¶
- 所有 WS 客户端(操作员 + Nodes)在
connect中包含 设备身份。 - 新设备 ID 需要配对审批。Gateway 为后续连接颁发 设备令牌。
- 直接本地回环连接可以自动批准,以保持同主机体验顺畅。
- OpenClaw 还有一个狭窄的后端/容器本地自连接路径,用于 受信任的共享密钥 helper 流程。
- Tailnet 和 LAN 连接,包括同主机 tailnet 绑定,仍然需要 显式配对审批。
- 所有连接都必须对
connect.challenge随机数签名。签名负载v3还绑定platform和deviceFamily。Gateway 在重连时固定已配对元数据, 并要求元数据变更时进行修复配对。 - 非本地 连接仍需要显式审批。
- Gateway 认证(
gateway.auth.*)仍然适用于 所有 连接,无论本地还是 远程。
详情:Gateway 协议、配对、 安全。
协议类型与代码生成¶
- TypeBox 模式定义协议。
- JSON Schema 从这些模式生成。
- Swift 模型从 JSON Schema 生成。
远程访问¶
- 首选:Tailscale 或 VPN。
- 替代方案:SSH 隧道
- 相同的握手 + 认证令牌适用于隧道。
- 在远程设置中,可以为 WS 启用 TLS + 可选固定。
运维快照¶
- 启动:
openclaw gateway(前台,日志输出到 stdout)。 - 健康:通过 WS 的
health(也包含在hello-ok中)。 - 监督:使用 launchd/systemd 自动重启。
定时工作与关闭¶
Gateway 内核拥有一个 GatewayScheduler,用于已注册的维护和 cron 唤醒。所有者接收该实例并注册任务;一个主机定时器驱动下一次唤醒。对于持久性工作,存储保留截止时间,其所有者在启动时重建计划,而不是持久化第二个调度器状态。
睡眠后,迟到的唤醒会为每次可运行、到期的注册项在该次唤醒中分派一次。周期性注册会等待其回调和跟踪工作完成,然后才开始下一个间隔;错过的 tick 会被合并。墙钟时间弥补睡眠,而经过时间使相对延迟和节奏在时钟向后校正时继续推进。重新调度默认替换等待中的任务;mode: "earliest" 为同一任务 ID 保留更早的墙钟和经过截止时间,因此陈旧读取无法推迟已经承诺的唤醒。
beginClose() 关闭调度准入,取消待处理的唤醒,并发出关闭信号。stop() 会等待已在运行的回调以及由其异步作用域跟踪的工作完成;Gateway 生命周期负责外层关闭预算和资源拆除。请求截止时间、流本地定时器和子进程清理仍由其操作所有者负责。SQLite WAL 检查点定时器仍由存储所有者负责。
不变量¶
- 每个主机上,恰好一个 Gateway 控制单个 Baileys 会话。
- 握手是强制的。任何非 JSON 或非 connect 的首帧都会导致强制关闭。
- 事件不会重放。客户端在出现间隙时必须刷新。
相关¶
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw