WebSocket Ping 与 TCP Keepalive 在代理下的取舍
为 WebSocket 对端选择一种存活检测,而不是把仍然活着的 TCP 套接字当作应用路径正在响应的证据。
活着的 TCP 套接字、有响应的 WebSocket 对端和应用层面的有效进展,是三种不同的观察:
| 证据 | 它能确立什么 |
|---|---|
| TCP 层存活 | 所检查的传输路径在该层有响应 |
| 匹配的 WebSocket Pong | 对端应答了该控制帧 |
| 应用层确认 | 应用按其自身协议确认了一次操作 |
正向代理通常会分别维护面向客户端和面向目标的连接。客户端的 TCP 对端是代理,而已建立隧道内的 Ping 会一路到达 WebSocket 端点。
匹配的 Pong
协议要求应答的 Pong 携带 Ping 的应用数据。用这种对应关系来识别尚未完成的探测。未经请求的 Pong 是允许的,但它并不请求确认;在每条数据消息之后发送 Pong 所提供的证据并不相同。
优先使用库所支持的心跳机制。浏览器 JavaScript 则需要一套应用层心跳约定。请根据工作负载和网络策略选择间隔与失败阈值。调度暂停或事件循环过载都可能错过激进的阈值,却并未确立网络已经失败。
让接收方持续运行
客户端需要持续的 I/O 才能接收并处理控制帧。阻塞这套机制会让本地资源饥饿看起来像一次中断。
Ping 会产生隧道流量,但每个中间环节自行决定什么才算满足其空闲策略。没有任何心跳能保证免受连接绝对寿命上限的影响。
对端可以在其应用停止产生更新时仍然应答 Ping,而一个安静的订阅也可能是健康的。当两者都重要时,请分别跟踪最后一次有效的 Pong 和有意义的应用事件。发生故障时,保留路由、耗时和未完成的探测,然后通过受支持的生命周期关闭或恢复。