AI 编程教程中文版
官方教程中文版Gateway 运行时

理解 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。
  • 推送 agentchatpresencehealthheartbeatcron 等事件。

控制端 clients:

  • CLI、macOS app、Web admin、自动化脚本都属于控制端。
  • 每个 client 建立一条 WebSocket 连接。
  • 常见请求包括 healthstatussendagentsystem-presence

Nodes:

  • node 不是 Gateway,也不接管消息渠道。
  • node 用 role: "node" 连接同一个 WebSocket server。
  • node 暴露设备能力,例如 canvas.*camera.*device.*notifications.*screen.recordlocation.getsystem.*

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 要幂等键sendagent 这类请求重试时不能重复副作用

5. Pairing 和本地信任

所有 WebSocket 客户端和 nodes 都会在 connect 阶段带设备身份。新设备 ID 需要 pairing approval,Gateway 会给后续连接发 device token。

可以这样理解:

  • 本机 loopback 连接可以有更顺滑的体验。
  • 非本地连接仍然需要显式 approval。
  • Gateway 的 gateway.auth.* 仍然适用于本地和远程连接。
  • Tailscale、trusted proxy、shared-secret 只是不同认证入口,不是绕过 pairing 的理由。
  • 所有连接都要签名 connect.challenge nonce。

这也是为什么官方安全文档反复强调:OpenClaw 是个人助手信任模型,不是给互不信任用户共享一个 Agent 的多租户边界。

6. Canvas 和 A2UI

Gateway HTTP server 也承载两个内置路径:

/__openclaw__/canvas/
/__openclaw__/a2ui/

它们复用 Gateway 端口。Canvas 面向 Agent 可编辑的 HTML/CSS/JS,A2UI 面向 Agent-to-UI 的交互宿主。你不需要把它们理解成单独服务;它们属于 Gateway 运行时的一部分。

7. 远程访问

远程访问优先级:

  1. Tailscale 或 VPN。
  2. SSH tunnel。
  3. 有明确认证、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. 本章自检

  1. Gateway、Client、Node 的分工分别是什么?
  2. 为什么一个 host 上不应该让多个 Gateway 抢同一组渠道?
  3. 远程访问为什么优先保留 loopback,再用 Tailscale 或 SSH tunnel?

过关标准:你能用一句话说清 —— “Gateway 是 OpenClaw 的长期控制面,所有客户端和 nodes 都通过它连接,远程访问也不能绕过 auth、pairing 和 loopback-first 的默认安全边界。”

11. 接下来去哪

12. 官方资料

本页目录