·
#踩坑#WebSocket#网络
别再用 ws:// 了,过 NAT 必死
一次 WebSocket 反复掉线的排查,最后的结论很简单:上 wss + 443
ClawMo iOS 客户端连 OpenClaw Gateway,用 ws:// 18789 在 4G 网络下频繁掉线,但 Wi-Fi 又一切正常。 排查了客户端心跳、服务端 keepalive、Caddy 配置,最后发现问题根源完全不在代码里。
现象
- Wi-Fi:稳如老狗,几小时不掉
- 4G:平均 30 秒到 2 分钟必断一次
- 掉线时客户端没有任何错误码,TCP 直接 RST
真正的原因
运营商 NAT 设备会主动清理它认为「不活跃」的 TCP 连接。 心跳间隔短一点(比如 10 秒)能延缓这个过程,但只要连接被识别为非标端口的明文,就有概率被截。
更阴险的是:很多企业网关、咖啡馆 Wi-Fi 也会做类似的事。ws:// 在生产里就是不可靠。
解法
换成 wss:// + 443 端口。具体到我的部署:
wss://clawmo.larryzheng.cn → Caddy → localhost:18789
Caddy 配置反代 + 自动证书,客户端只改一行 URL。上线之后没再掉过。
教训
- 凡是要过公网的 WebSocket,默认就要 wss + 443,不要省
- 别在 18789 这种「业务端口」直接对外,用域名 + 反代
- 心跳是兜底,不是主线