WebSocket在代理环境下“连上几分钟就断”,不能直接归因于IP不稳定。一条连接会经过客户端、代理、NAT、防火墙、负载均衡和应用服务,只要其中一层回收空闲状态,客户端就会收到关闭、重置或超时。
排障的关键是先确认断开发生在握手前、刚升级后,还是长时间空闲后,再决定查认证、协议、心跳还是网络。
一、WebSocket连接经历哪些阶段
| 阶段 | 主要动作 | 常见故障 |
|---|---|---|
| DNS | 解析代理和目标域名 | 解析失败、IPv4/IPv6路径不同 |
| 代理连接 | 连接代理并完成认证 | 407、端口不可达、白名单错误 |
| TLS | wss建立安全连接 | 证书、SNI、系统时间错误 |
| HTTP升级 | 发送Upgrade请求,期望101 | 头部被删、代理不支持升级 |
| 长连接 | 双向传输帧 | 空闲超时、NAT回收、链路抖动 |
| 关闭/重连 | 关闭码、退避、恢复会话 | 重试风暴、消息重复或丢失 |
二、握手失败先看HTTP状态
WebSocket最初是HTTP请求。成功升级通常返回101 Switching Protocols。若出现407,先处理代理认证;502、503或504则按网关、容量和超时分层定位;403可能来自目标授权或安全策略。
通用状态码排查见代理407、502、503、504处理。不要看到403就更换IP继续连接,应检查访问许可、请求头和服务端日志。
三、HTTP代理需要支持CONNECT和Upgrade
对于 wss://,客户端通常先通过CONNECT建立TLS隧道,再在隧道中完成WebSocket升级。对于明文 ws://,代理可能直接看到Upgrade头。中间代理若不转发 Upgrade 和 Connection,握手就会失败。
企业反向代理还要确认HTTP版本和升级配置。不要把“网页能打开”当作WebSocket路径一定可用,因为普通请求不需要保持同样的长连接。
四、固定时间断线通常暗示什么
如果每次都在近似30秒、60秒或几分钟断开,优先检查各层的空闲超时:
- 客户端WebSocket库的ping/pong和读取超时;
- 代理服务端的空闲连接回收;
- NAT与防火墙状态表;
- 负载均衡器或反向代理超时;
- 应用服务端的会话与心跳策略。
固定IP只表示地址相对稳定,不代表TCP连接永不重建。相关原理见静态代理仍会断线的原因。
五、心跳应该由谁发送
WebSocket协议定义ping/pong控制帧,但浏览器JavaScript通常不能直接发送底层ping,需要应用层消息或服务端机制。不同客户端库的默认行为也不同。
心跳间隔应短于已确认的空闲超时,同时避免过于频繁。服务端要区分心跳和业务消息,并对超时连接主动清理。没有服务端配合,客户端盲目发送字符串“ping”未必有意义。
六、代理认证会在长连接中重复吗
通常认证发生在建立代理连接或CONNECT隧道时。连接保持期间不会为每个WebSocket帧重新认证,但重连时会重新建立连接并验证凭据。密码轮换后,旧连接可能继续存活,新连接却开始报407。
因此轮换代理凭据时要观察旧长连接寿命,并按代理账号密码无中断轮换流程分批处理。
七、安全重连不能立即无限循环
建议使用指数退避和随机抖动,例如从短间隔开始逐步增加,并设置最大等待和最大连续失败次数。恢复后再重置计数。
- 认证失败、权限拒绝等确定性错误不自动无限重试;
- 服务器维护时尊重Retry-After或状态页;
- 网络波动可有限重试;
- 达到阈值后熔断并通知人工;
- 多个客户端加入随机抖动,避免同时重连。
八、消息如何避免重复和丢失
重连成功不等于会话自动恢复。关键业务应给消息分配唯一ID或序列号,由服务端确认已处理位置;客户端只重发未确认且允许重试的消息。写操作必须幂等,否则断线重发可能造成重复提交。
对于订阅流,应明确重连后从最新状态、指定游标还是完整快照恢复。
九、最小日志应该记录什么
| 字段 | 用途 |
|---|---|
| 连接ID与节点ID | 关联代理和服务端日志 |
| DNS、TCP、TLS、升级耗时 | 定位失败阶段 |
| HTTP状态和WebSocket关闭码 | 区分握手与会话故障 |
| 连接持续时间与最后消息时间 | 识别空闲超时 |
| 重连次数与退避时间 | 发现重试风暴 |
| 客户端、网络和配置版本 | 确定影响范围 |
不要记录代理密码、Cookie、令牌或完整业务消息。
十、推荐的对照测试
- 在相同客户端下比较直连和代理;
- 比较HTTP代理与明确支持的SOCKS5路径;
- 用自有WebSocket测试服务设置已知心跳和超时;
- 分别测试有业务消息和完全空闲的连接;
- 在WiFi与有线网络下复测;
- 对照代理、负载均衡和应用服务端时间线。
只有单个第三方服务失败时,先确认该服务是否允许代理和WebSocket访问。完整结论应指出断线阶段、触发条件和恢复方式,而不是笼统写“换IP解决”。






