理解 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 為什麼構成長期助手。