理解 Gateway 架构
理解 OpenClaw Gateway 架构:长期控制面、WebSocket 协议、nodes、pairing、本机 loopback、远程访问和运行不变量。
OpenClaw 的中心不是某个聊天窗口,而是 Gateway。Gateway 是一个长期运行的控制面,负责接入消息渠道、维护会话、调度 Agent、暴露 WebSocket 控制接口,并把 CLI、Web UI、macOS app、移动端、nodes 和自动化任务收束到同一个运行时。
这一章用 13 分钟换什么:你会知道为什么 OpenClaw 不是一次性 CLI,为什么默认监听 127.0.0.1:18789,为什么一个 host 只该有一个 Gateway,以及远程访问为什么优先走 Tailscale / SSH tunnel。
1. 一句话理解 Gateway
Gateway 是 OpenClaw 的控制面。
它做四件事:
- 连接消息平台,例如 WhatsApp、Telegram、Slack、Discord、Signal、iMessage、WebChat。
- 接收控制端连接,例如 CLI、macOS app、Web UI、自动化脚本。
- 接收 node 连接,例如 macOS、iOS、Android 或 headless 节点暴露的设备能力。
- 负责会话、健康状态、心跳、cron、hooks 和 Agent 运行事件。
默认情况下,控制面监听在:
127.0.0.1:18789这个默认值很关键:OpenClaw 默认把 Gateway 放在本机回环地址上,而不是直接暴露到公网。
flowchart TD
Gateway["Gateway"]
Channels["消息渠道"]
Clients["控制端客户端"]
Nodes["Nodes"]
Agents["Agents"]
State["sessions / auth / health"]
UI["Canvas / A2UI / Control UI"]
Channels --> Gateway
Clients --> Gateway
Nodes --> Gateway
Gateway --> Agents
Gateway --> State
Gateway --> UI
style Gateway fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
style Channels fill:#dcfce7,stroke:#22c55e,stroke-width:2px
style Nodes fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
style State fill:#fee2e2,stroke:#ef4444,stroke-width:2px
Gateway 不是聊天界面:聊天界面只是一个客户端。真正持有渠道连接、session、auth profiles 和运行状态的是 Gateway。
2. 组件分工
Gateway daemon:
- 维护各个 provider 的连接。
- 暴露 typed WebSocket API。
- 按 JSON Schema 校验入站 frame。
- 推送
agent、chat、presence、health、heartbeat、cron等事件。
控制端 clients:
- CLI、macOS app、Web admin、自动化脚本都属于控制端。
- 每个 client 建立一条 WebSocket 连接。
- 常见请求包括
health、status、send、agent、system-presence。
Nodes:
- node 不是 Gateway,也不接管消息渠道。
- node 用
role: "node"连接同一个 WebSocket server。 - node 暴露设备能力,例如
canvas.*、camera.*、device.*、notifications.*、screen.record、location.get、system.*。
WebChat:
- WebChat 是静态聊天界面。
- 它通过 Gateway WebSocket API 读历史和发送消息。
- 远程部署时,它应该走同一条 SSH 或 Tailscale 入口,而不是另开一个无保护入口。
| 组件 | 负责什么 | 不负责什么 |
|---|---|---|
| Gateway | 渠道连接、控制面、session、事件、Agent 调度 | 不直接代表某个聊天 UI |
| Client | 发控制请求、展示状态、发送消息 | 不持有渠道 session |
| Node | 暴露设备能力和远端执行面 | 不运行 Gateway 服务 |
| WebChat | 静态聊天页面 | 不替代 Gateway auth 和 pairing |
3. 为什么官方强调一个 host 一个 Gateway
一个 host 上只应该有一个长期 Gateway 控制同一组渠道状态。尤其是 WhatsApp 这类渠道,官方架构里强调 Gateway 是打开会话的唯一位置。
如果同一台机器起多个 Gateway 去抢同一个渠道,会出现三类问题:
- provider session 被重复登录或互相踢下线。
- session、pairing、allowlist、cron 状态分裂。
- Agent 记忆和 workspace 写入分叉,排障时无法判断哪个进程是真正入口。
实践判断很简单:一个机器、一个信任边界、一个 Gateway。
多 Gateway 不是横向扩容捷径:除非你有明确隔离 profile、隔离渠道和隔离 workspace,否则多个 Gateway 会先带来状态分裂,而不是稳定性。
4. WebSocket 握手
Gateway 的协议是 WebSocket 文本 frame,payload 是 JSON。第一帧必须是 connect。握手后才进入请求、响应和事件流。
常见结构可以理解为:
{ "type": "req", "id": "1", "method": "health", "params": {} }响应:
{ "type": "res", "id": "1", "ok": true, "payload": {} }事件:
{ "type": "event", "event": "health", "payload": {} }副作用请求需要 idempotency key,避免重试时重复发送消息或重复触发 Agent。
握手过程可以压成这张图:
sequenceDiagram
participant Client as Client / Node
participant Gateway as Gateway
Gateway-->>Client: connect.challenge
Client->>Gateway: req connect
Gateway-->>Client: res hello-ok
Gateway-->>Client: event presence
Client->>Gateway: req health / agent / send
Gateway-->>Client: res + event stream
| 规则 | 含义 |
|---|---|
第一帧必须是 connect | 非 JSON 或非 connect 首帧会被关闭 |
hello-ok 返回能力和快照 | 客户端知道 server 版本、methods、events、policy |
| events 不保证 replay | 客户端发现 gap 后要重新拉状态 |
| side-effect method 要幂等键 | send、agent 这类请求重试时不能重复副作用 |
5. Pairing 和本地信任
所有 WebSocket 客户端和 nodes 都会在 connect 阶段带设备身份。新设备 ID 需要 pairing approval,Gateway 会给后续连接发 device token。
可以这样理解:
- 本机 loopback 连接可以有更顺滑的体验。
- 非本地连接仍然需要显式 approval。
- Gateway 的
gateway.auth.*仍然适用于本地和远程连接。 - Tailscale、trusted proxy、shared-secret 只是不同认证入口,不是绕过 pairing 的理由。
- 所有连接都要签名
connect.challengenonce。
这也是为什么官方安全文档反复强调:OpenClaw 是个人助手信任模型,不是给互不信任用户共享一个 Agent 的多租户边界。
6. Canvas 和 A2UI
Gateway HTTP server 也承载两个内置路径:
/__openclaw__/canvas/
/__openclaw__/a2ui/它们复用 Gateway 端口。Canvas 面向 Agent 可编辑的 HTML/CSS/JS,A2UI 面向 Agent-to-UI 的交互宿主。你不需要把它们理解成单独服务;它们属于 Gateway 运行时的一部分。
7. 远程访问
远程访问优先级:
- Tailscale 或 VPN。
- SSH tunnel。
- 有明确认证、TLS、反向代理和审计的受控入口。
SSH tunnel 示例:
ssh -N -L 18789:127.0.0.1:18789 user@host这条命令的意思是:本机访问 127.0.0.1:18789,实际转发到远端机器的 Gateway loopback 端口。Gateway 仍然不用直接暴露公网端口。
| 远程方式 | 适合场景 | 关键边界 |
|---|---|---|
| Tailscale / VPN | 常驻主机、家用服务器、VPS | 仍然要 auth 和 pairing |
| SSH tunnel | 通用兜底、临时远程 | Gateway 保持 loopback-only |
| 受控反向代理 | 明确 TLS、auth、审计的部署 | 不给陌生公网裸露 WS |
gateway.remote.token 不是服务端认证开关:它是客户端凭据来源。服务端 auth 仍然要看 gateway.auth.* 或 trusted proxy 配置。
8. 运维快照
前台启动:
openclaw gateway查看状态:
openclaw health
openclaw status
openclaw gateway status生产使用时,应该交给 launchd、systemd 或 macOS app 监督重启。不要依赖一个临时终端窗口长期托管。
9. 不变量
- 一个 host 上一个 Gateway 控制同一套渠道。
- Gateway 默认监听 loopback。
- 第一帧必须是
connect。 - 非 JSON 或非
connect首帧会被关闭。 - events 不保证 replay,客户端发现事件 gap 后应该重新拉状态。
- 远程入口仍然需要 auth 和 pairing。
- Nodes 是外围设备能力,不是 Gateway 服务。
- WebChat 复用 Gateway WebSocket,不是单独安全边界。
排架构问题先找唯一入口:消息平台、UI、CLI、node 和自动化最终都回到 Gateway;如果状态分裂,先确认是不是启动了多个控制面或多个 profile。
10. 本章自检
- Gateway、Client、Node 的分工分别是什么?
- 为什么一个 host 上不应该让多个 Gateway 抢同一组渠道?
- 远程访问为什么优先保留 loopback,再用 Tailscale 或 SSH tunnel?
过关标准:你能用一句话说清 —— “Gateway 是 OpenClaw 的长期控制面,所有客户端和 nodes 都通过它连接,远程访问也不能绕过 auth、pairing 和 loopback-first 的默认安全边界。”
11. 接下来去哪
Gateway 配置
架构看懂后,继续看配置文件、schema、热加载和排障。
安全与远程访问
如果你准备远程打开 Control UI,先读安全边界。
理解:为什么 AI 需要一个家
从原理篇回看 Gateway、Memory、Channel 和 Agent 为什么构成长期助手。