Skip to content

Gateway service runbook

最后更新:2025-12-09

它是什么

  • 一个常驻进程:拥有单一的 Baileys/Telegram 连接,以及控制/事件平面。
  • 取代旧的 gateway 命令。CLI 入口:openclaw gateway
  • 持续运行直到停止;遇到致命错误会以非 0 退出,以便 supervisor 重启它。

如何运行(本地)

bash
openclaw gateway --port 18789
# 如果你需要在 stdio 中看到完整 debug/trace 日志:
openclaw gateway --port 18789 --verbose
# 如果端口忙,先终止监听再启动:
openclaw gateway --force
# 开发循环(TS 变更自动重载):
pnpm gateway:watch
  • Config 热重载会监视 ~/.openclaw/openclaw.json(或 OPENCLAW_CONFIG_PATH)。
    • 默认模式:gateway.reload.mode="hybrid"(安全变更热应用;关键变更重启)。
    • 需要重启时,热重载会使用进程内重启并发送 SIGUSR1
    • gateway.reload.mode="off" 禁用。
  • WebSocket 控制面默认绑定到 127.0.0.1:<port>(默认 18789)。
  • 同一端口也会提供 HTTP(Control UI、hooks、A2UI),单端口复用。
  • 默认会在 canvasHost.port(默认 18793)启动 Canvas 文件服务器:从 ~/.openclaw/workspace/canvas 提供 http://<gateway-host>:18793/__openclaw__/canvas/。 通过 canvasHost.enabled=falseOPENCLAW_SKIP_CANVAS_HOST=1 禁用。
  • 日志输出到 stdout;使用 launchd/systemd 保活并做日志轮转。
  • 排障时可用 --verbose:把 log file 中的 debug 日志(握手、req/res、events)镜像到 stdio。
  • --force 会用 lsof 找出选择端口上的 listeners,发送 SIGTERM,记录被杀掉的进程,然后启动 gateway(如果缺少 lsof 会快速失败)。
  • 如果你在 supervisor 下运行(launchd/systemd/mac app child-process mode),stop/restart 通常会发送 SIGTERM;旧版本可能会表现为 pnpmELIFECYCLE 退出码 143(SIGTERM),这是正常关闭而不是崩溃。
  • SIGUSR1 在被授权时触发进程内重启(gateway tool/config apply/update,或启用 commands.restart 允许手动重启)。
  • 默认需要 Gateway auth:设置 gateway.auth.token(或 OPENCLAW_GATEWAY_TOKEN)或 gateway.auth.password。 客户端必须发送 connect.params.auth.token/password,除非使用 Tailscale Serve identity。
  • 向导现在默认会生成 token,即使是在 loopback 模式。
  • 端口优先级:--port > OPENCLAW_GATEWAY_PORT > gateway.port > 默认 18789

远程访问

  • 优先使用 Tailscale/VPN;否则使用 SSH 隧道:
    bash
    ssh -N -L 18789:127.0.0.1:18789 user@host
  • 客户端随后通过隧道连接 ws://127.0.0.1:18789
  • 如果配置了 token,即使走隧道客户端也必须在 connect.params.auth.token 中携带它。

多个 gateways(同一主机)

通常没必要:一个 Gateway 能服务多个消息 channels 与 agents。只有在冗余或严格隔离(例如 rescue bot)场景下才需要多个 Gateways。

只要你隔离 state + config 并使用唯一端口,该方案就受支持。完整指南见:Multiple gateways

service 名称会随 profile 变化:

  • macOS:bot.molt.<profile>(可能仍存在 legacy com.openclaw.*
  • Linux:openclaw-gateway-<profile>.service
  • Windows:OpenClaw Gateway (<profile>)

安装元信息会写入 service config:

  • OPENCLAW_SERVICE_MARKER=openclaw
  • OPENCLAW_SERVICE_KIND=gateway
  • OPENCLAW_SERVICE_VERSION=<version>

Rescue-Bot 模式:保持第二个 Gateway 隔离,使用独立 profile/state dir/workspace,并预留足够的 base port 间隔。完整指南见:Rescue-bot guide

Dev profile(--dev

快速路径:运行一个完全隔离的 dev 实例(config/state/workspace),不影响你的主配置。

bash
openclaw --dev setup
openclaw --dev gateway --allow-unconfigured
# 然后把 CLI 指向 dev 实例:
openclaw --dev status
openclaw --dev health

默认值(可通过 env/flags/config 覆盖):

  • OPENCLAW_STATE_DIR=~/.openclaw-dev
  • OPENCLAW_CONFIG_PATH=~/.openclaw-dev/openclaw.json
  • OPENCLAW_GATEWAY_PORT=19001(Gateway WS + HTTP)
  • browser control service port = 19003(派生:gateway.port+2,仅 loopback)
  • canvasHost.port=19005(派生:gateway.port+4
  • 当你在 --dev 下运行 setup/onboardagents.defaults.workspace 默认会变成 ~/.openclaw/workspace-dev

派生端口(经验规则):

  • Base port = gateway.port(或 OPENCLAW_GATEWAY_PORT / --port
  • browser control service port = base + 2(仅 loopback)
  • canvasHost.port = base + 4(或 OPENCLAW_CANVAS_HOST_PORT / config 覆盖)
  • Browser profile CDP 端口从 browser.controlPort + 9 .. + 108 自动分配(按 profile 持久化)。

每个实例的检查清单:

  • 唯一的 gateway.port
  • 唯一的 OPENCLAW_CONFIG_PATH
  • 唯一的 OPENCLAW_STATE_DIR
  • 唯一的 agents.defaults.workspace
  • 独立的 WhatsApp 号码(如果使用 WA)

按 profile 安装 service:

bash
openclaw --profile main gateway install
openclaw --profile rescue gateway install

示例:

bash
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json OPENCLAW_STATE_DIR=~/.openclaw-a openclaw gateway --port 19001
OPENCLAW_CONFIG_PATH=~/.openclaw/b.json OPENCLAW_STATE_DIR=~/.openclaw-b openclaw gateway --port 19002

协议(operator 视角)

  • 完整文档:Gateway protocolBridge protocol(legacy)
  • 客户端必需的第一帧:req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{id,displayName?,version,platform,deviceFamily?,modelIdentifier?,mode,instanceId?}, caps, auth?, locale?, userAgent? } }
  • Gateway 回复:res {type:"res", id, ok:true, payload:hello-ok }(或 ok:false 带 error,然后关闭连接)。
  • 握手完成后:
    • Requests:{type:"req", id, method, params}{type:"res", id, ok, payload|error}
    • Events:{type:"event", event, payload, seq?, stateVersion?}
  • 结构化 presence 条目:{host, ip, version, platform?, deviceFamily?, modelIdentifier?, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId? }(对 WS clients,instanceId 来自 connect.client.instanceId)。
  • agent 响应是两阶段:先 res ack {runId,status:"accepted"},run 结束后再返回最终 res {runId,status:"ok"|"error",summary};流式输出通过 event:"agent" 发送。

Methods(初始集合)

  • health — 完整 health snapshot(与 openclaw health --json 同结构)。
  • status — 简短摘要。
  • system-presence — 当前 presence 列表。
  • system-event — 发布一条 presence/system note(结构化)。
  • send — 通过活跃 channel(s) 发送消息。
  • agent — 运行一次 agent turn(在同一连接上回传 events)。
  • node.list — 列出已配对 + 当前已连接的 nodes(包含 capsdeviceFamilymodelIdentifierpairedconnected 与广播的 commands)。
  • node.describe — 描述某个 node(capabilities + 支持的 node.invoke commands;对已配对 nodes 与当前已连接但未配对 nodes 均可用)。
  • node.invoke — 在 node 上调用命令(例如 canvas.*camera.*)。
  • node.pair.* — 配对生命周期(requestlistapproverejectverify)。

另见:Presence(解释 presence 如何产生/去重,以及稳定的 client.instanceId 为什么重要)。

Events

  • agent — agent run 的流式 tool/output events(带 seq)。
  • presence — presence 更新(带 stateVersion 的增量),推送给所有连接的客户端。
  • tick — 周期性 keepalive/no-op,用于确认存活。
  • shutdown — Gateway 即将退出;payload 包含 reason 与可选的 restartExpectedMs。客户端应重连。

WebChat 集成

  • WebChat 是一个原生 SwiftUI UI,直接通过 Gateway WebSocket 获取历史、发送、abort 与 events。
  • 远程使用走同一条 SSH/Tailscale 隧道;如果配置了 gateway token,客户端会在 connect 时携带它。
  • macOS app 通过一个共享 WS 连接;它从初始 snapshot 注入 presence,并监听 presence events 来更新 UI。

类型与校验

  • 服务端用 AJV 对每个入站 frame 做校验,schema 来自协议定义生成的 JSON Schema。
  • 客户端(TS/Swift)消费生成的类型(TS 直接使用;Swift 使用仓库里的 generator)。
  • 协议定义是事实来源;用以下命令重新生成 schema/models:
    • pnpm protocol:gen
    • pnpm protocol:gen:swift

连接快照(Connection snapshot)

  • hello-ok 会包含一个 snapshot,其中含 presencehealthstateVersionuptimeMs,以及 policy {maxPayload,maxBufferedBytes,tickIntervalMs},使客户端无需额外请求即可立即渲染。
  • health/system-presence 仍可用于手动刷新,但 connect 时不是必需。

错误码(res.error 结构)

  • Errors 使用 { code, message, details?, retryable?, retryAfterMs? }
  • 标准 codes:
    • NOT_LINKED — WhatsApp 未鉴权。
    • AGENT_TIMEOUT — agent 未在配置的 deadline 内响应。
    • INVALID_REQUEST — schema/参数校验失败。
    • UNAVAILABLE — Gateway 正在关闭或依赖不可用。

Keepalive 行为

  • 周期性发出 tick events(或 WS ping/pong),使客户端在无流量时也能确认 Gateway 存活。
  • send/agent 的 acknowledgements 仍是独立的 responses;不要用 ticks 代替 send 的 ack。

Replay / gaps

  • events 不会 replay。客户端检测到 seq gap 时,应在继续前刷新(health + system-presence)。WebChat 与 macOS 客户端现在会在 gap 时自动刷新。

Supervision(macOS 示例)

  • 使用 launchd 保持 service 存活:
    • Program:openclaw 的路径
    • Arguments:gateway
    • KeepAlive:true
    • StandardOut/Err:文件路径或 syslog
  • 出错时 launchd 会重启;致命的 misconfig 应持续退出,以便 operator 注意到。
  • LaunchAgents 是按用户的,且需要登录态;对 headless 需要自建 LaunchDaemon(不随项目提供)。
    • openclaw gateway install 会写入 ~/Library/LaunchAgents/bot.molt.gateway.plist (或 bot.molt.<profile>.plist;同时会清理 legacy com.openclaw.*)。
    • openclaw doctor 会审计 LaunchAgent 配置,并可更新为当前默认值。

Gateway service 管理(CLI)

使用 Gateway CLI 做 install/start/stop/restart/status:

bash
openclaw gateway status
openclaw gateway install
openclaw gateway stop
openclaw gateway restart
openclaw logs --follow

备注:

  • gateway status 默认会用 service 解析到的端口/config probe Gateway RPC(可用 --url 覆盖)。
  • gateway status --deep 会增加系统级扫描(LaunchDaemons/system units)。
  • gateway status --no-probe 会跳过 RPC probe(网络不通时有用)。
  • gateway status --json 对脚本稳定。
  • gateway status 会分别报告 supervisor runtime(launchd/systemd 是否在运行)与 RPC reachability(WS connect + status RPC)。
  • gateway status 会打印 config path + probe target,避免 “localhost vs LAN bind” 混淆与 profile 不匹配。
  • 当 service 看似运行但端口关闭时,gateway status 会包含最后一条 gateway 错误行。
  • logs 通过 RPC tail Gateway 文件日志(无需手动 tail/grep)。
  • 如果检测到其它类似 gateway 的 services,CLI 会警告,除非它们是 OpenClaw profile services。 大多数场景仍建议 一机一个 gateway;若要冗余或 rescue bot,请用隔离 profiles/ports。见 Multiple gateways
    • 清理:openclaw gateway uninstall(当前 service)与 openclaw doctor(legacy migrations)。
  • gateway install 在已安装时是 no-op;使用 openclaw gateway install --force 重装(profile/env/path 变更)。

Bundled mac app:

  • OpenClaw.app 可打包一个基于 Node 的 gateway relay,并安装一个 per-user 的 LaunchAgent,label 为 bot.molt.gateway(或 bot.molt.<profile>;legacy com.openclaw.* labels 仍会被干净卸载)。
  • 要干净停止,使用 openclaw gateway stop(或 launchctl bootout gui/$UID/bot.molt.gateway)。
  • 要重启,使用 openclaw gateway restart(或 launchctl kickstart -k gui/$UID/bot.molt.gateway)。
    • launchctl 只有在 LaunchAgent 已安装时可用;否则先运行 openclaw gateway install
    • 运行命名 profile 时,将 label 替换为 bot.molt.<profile>

Supervision(systemd user unit)

OpenClaw 在 Linux/WSL2 上默认安装 systemd user service。 对单用户机器推荐 user services(环境更简单、per-user config)。 对多用户或 always-on 服务器推荐 system service(无需 lingering、共享 supervision)。

openclaw gateway install 会写入 user unit。openclaw doctor 会审计 unit 并可更新为当前推荐默认值。

创建 ~/.config/systemd/user/openclaw-gateway[-<profile>].service

[Unit]
Description=OpenClaw Gateway (profile: <profile>, v<version>)
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/openclaw gateway --port 18789
Restart=always
RestartSec=5
Environment=OPENCLAW_GATEWAY_TOKEN=
WorkingDirectory=/home/youruser

[Install]
WantedBy=default.target

启用 lingering(必需:使 user service 在登出/空闲后仍存活):

sudo loginctl enable-linger youruser

Onboarding 会在 Linux/WSL2 上执行此操作(可能提示 sudo;写入 /var/lib/systemd/linger)。 然后启用 service:

systemctl --user enable --now openclaw-gateway[-<profile>].service

替代方案(system service):对 always-on 或多用户服务器,可以安装 systemd system unit(无需 lingering)。 创建 /etc/systemd/system/openclaw-gateway[-<profile>].service(复制上面的 unit,把 WantedBy 改为 multi-user.target,设置 User= + WorkingDirectory=),然后:

sudo systemctl daemon-reload
sudo systemctl enable --now openclaw-gateway[-<profile>].service

Windows(WSL2)

Windows 安装应使用 WSL2 并遵循上面的 Linux systemd 章节。

运维检查

  • 存活性(Liveness):打开 WS 并发送 req:connect → 期望收到 respayload.type="hello-ok"(带 snapshot)。
  • 就绪性(Readiness):调用 health → 期望 ok: true,且 linkChannel 中存在已连接的 channel(如适用)。
  • Debug:订阅 tickpresence events;确认 status 显示 linked/auth age;presence 条目显示 Gateway host 与已连接客户端。

安全保证

  • 默认假设一机一个 Gateway;如果你运行多个 profiles,请隔离 ports/state,并指向正确实例。
  • 不会 fallback 到直连 Baileys;如果 Gateway down 了,发送会快速失败。
  • 非 connect 的首帧或不合法 JSON 会被拒绝并关闭 socket。
  • 优雅关闭:在关闭前发出 shutdown event;客户端必须处理 close + reconnect。

CLI 辅助命令

  • openclaw gateway health|status — 通过 Gateway WS 请求 health/status。
  • openclaw message send --target <num> --message "hi" [--media ...] — 通过 Gateway 发送(对 WhatsApp 幂等)。
  • openclaw agent --message "hi" --to <num> — 运行一次 agent turn(默认等待最终结果)。
  • openclaw gateway call <method> --params '{"k":"v"}' — 用于排障的原始 method invoker。
  • openclaw gateway stop|restart — 停止/重启被 supervisor 管理的 gateway service(launchd/systemd)。
  • gateway helper 子命令假设 --url 指向一个运行中的 gateway;它们不再自动拉起 gateway。

迁移指引

  • 逐步淘汰对旧 openclaw gateway 与 legacy TCP control port 的依赖。
  • 更新客户端以使用 WS 协议,并要求 mandatory connect 与结构化 presence。