发布时间: 2026年10月21日更新时间: 2026年10月21日

WebSocket 代理如何保持长连接:超时、保活与重连

WebSocket 断连可按握手阶段、空闲时间和各层日志排查。区分读取空闲超时、连接总时长与应用心跳,并按实际链路设置重连策略。

WebSocket 断开可能发生在握手、代理转发、CDN、负载均衡或后端应用。固定间隔断开可作为调查线索,但不能仅凭秒数认定是哪一层。本文说明如何检查各层配置、实现心跳并记录重连结果。

根据断连时间判断客户端、代理或中间层故障

一条 WebSocket 链路至少有五层:客户端、代理、CDN、负载均衡、后端应用。定位方法是看断开的时间间隔:

  • 固定间隔断开:检查该时长是否与 Nginx、CDN、负载均衡或应用配置吻合
  • 无规律断开:对照代理、客户端和后端日志,检查异常关闭及网络错误

先记录断开时刻、连接阶段和关闭原因,再对照各层配置与日志。若仅特定目标失败,也应检查该目标的响应和上游路径,不直接归因于出口。

Nginx、CDN、负载均衡和后端的空闲超时

层应核对的设置调整方向
Nginxproxy_read_timeout 及版本适用行为按上游读取空闲间隔和应用心跳配置
Caddystream_timeout(连接总时长)及重载行为不把总时长上限当作空闲超时
CDN 与负载均衡当前套餐和监听器的空闲策略查实际配置及边缘/负载均衡日志
后端应用应用自身的空闲回收和连接寿命查框架配置与服务端日志

具体值随产品、套餐和版本变化,使用前核对 Cloudflare WebSocket 文档 与 Caddy reverse_proxy 文档,并以实际运行日志为准。

注意最后两行:即使代理层调好了,后端仍可能主动回收空闲连接,表现同样是"固定时间断"。如果是握手阶段直接失败、而不是连上之后被断,先按报错类型分开看:超时、连接被拒、证书错误各自对应不同的层。

按链路最短超时设置 WebSocket ping 间隔

若中间层按空闲时间关闭连接,可用应用层心跳维持应用活动;间隔应根据实际空闲策略和网络抖动设置,不设通用秒数。下面仅为演示应用层消息的示例,需由服务端实现对应响应与超时处理:

```javascript
const timer = setInterval(() => { // ws 为已建立的连接
if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: "ping" }));
}, intervalMs); // intervalMs 按实际链路配置
ws.addEventListener("close", () => clearInterval(timer));
ws.addEventListener("error", () => clearInterval(timer));
```

服务端应回复应用层心跳,客户端需设置应答截止时间;超时后按应用策略关闭连接并进入退避重连。浏览器 API 不提供发送协议控制帧的接口,本文 JSON 是应用层消息;支持原生 ping 的服务端库可按其文档使用协议 Ping/Pong。TCP keepalive 属于传输层连接检测,可能帮助发现失效连接或维护部分中间网络状态,但不能保证刷新所有 L7 空闲策略,也不能替代应用层心跳。连接未建立与建立后断开都先查对应阶段日志,不通过更换出口绕过目标站限制。

配置代理层以保持 WebSocket 升级和长连接

Nginx 如何配置 Upgrade 转发与读取空闲超时

传统 HTTP/1.1 Upgrade 需正确转发升级头;proxy_read_timeout 处理上游读取空闲间隔。响应缓冲不是握手成功的必要条件,出现消息延迟时应检查实际数据路径。Nginx 1.29.7 之前需显式配置 HTTP/1.1;示例保留该配置以兼容旧版本。代理鉴权见帮助中心代理设置,协议选择见HTTP、HTTPS、SOCKS5 代理怎么选。

```nginx
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;

按实际消息流行为决定是否需要调整 buffering

```

Caddy 默认处理升级,只在需要时调整超时

Caddy reverse_proxy 会处理 WebSocket 升级。stream_timeout 限制连接总时长,不是空闲超时;需区分重载时的 stream_close_delay。两边的配置差异见站内Caddy 与 Nginx 的 WebSocket 代理配置有什么区别。

用指数退避控制重连,并观察断连和握手指标

重连不要用固定间隔硬重试,否则断线瞬间所有客户端同时回来,形成二次冲击。用指数退避加抖动:首次 1 秒,之后每次翻倍,上限 30 秒,每档加 0—500 毫秒随机。

观察三个指标,就能判断问题是否解决:

指标正常范围异常含义
总连接尝试成功率按所有发起连接计数包含 DNS、TLS、认证、连接超时等失败
到达上游后的 Upgrade 成功率按到达上游的握手请求计数分析升级头、路径和上游响应
连接时长与关闭原因记录时长分布和关闭码固定时长或特定关闭码可提示调查方向
单位时间重连次数按客户端与时间段汇总尖峰提示需检查断开和重试策略

链路稳定之后,出口本身的可用性按代理 IP 可用率、延迟和稳定性怎么测试里的口径持续验证。

若日志确认连接确实因代理会话到期或出口切换而中断,可按实际会话时长和更换规则评估静态住宅代理 IP;代理类型不能修复应用、CDN 或后端超时配置。

FAQ

WebSocket 和长轮询哪个更适合穿透代理

WebSocket 更省资源,但对中间设备的升级支持要求高;长轮询兼容性好,代价是延迟和请求量。代理链路不确定时,长轮询是更稳的兜底。

ping 太频繁会有问题吗

会增加消息量和服务端负载。合适间隔取决于实测空闲策略、业务响应要求和网络抖动;应监控心跳应答延迟及超时,不采用未经验证的固定间隔。

断在 100 秒整说明什么

固定在约 100 秒断开只能作为排查线索,不能据此认定是 Cloudflare。核对 CDN、负载均衡和应用配置及日志;确认空闲回收后,再按实际策略评估心跳或超时设置。