WebSocket 长连接为什么会中断
WebSocket 长连接中断多数不是网络彻底故障,而是链路上某个有状态设备回收了连接:NAT、防火墙、CDN 都会清理空闲连接;心跳间隔过长、Wi-Fi 与移动数据切换、运营商对加密长连接的干扰、服务端重启同样会切断连接。有效的缓解思路是让心跳间隔小于链路上最短的空闲超时、避免中途切换网络,必要时更换传输方式或节点。
核心要点
- NAT、防火墙与 CDN 都会回收空闲连接,心跳间隔必须小于链路上最短的空闲超时才有保活效果。
- 手机在 Wi-Fi 与移动数据之间切换会改变出口地址与端口,原有 TCP 连接必然中断,WebSocket 只能重建。
- 长连接断开时延迟测试往往完全正常,因为测延迟新建的是短连接,与已有连接的存活状态无关。
- VMess、VLESS 常以 WebSocket 作为传输层并可经 CDN 转发,代理隧道自身的 ws 连接同样受空闲回收与干扰影响。
本文目录
一场进行到一半的视频会议突然掉线,SSH 会话放置十分钟后失去响应,网页应用的实时推送悄无声息地停止更新——这些现象的背后常常是同一件事:一条 WebSocket 或类似的长连接被中途切断。对代理用户来说,长连接中断尤其常见,因为数据要穿过比直连多得多的中间环节。本文梳理 WebSocket 长连接中断的主要原因、心跳保活的原理与可行的缓解方法。
WebSocket 在代理传输中的角色
WebSocket 最初为浏览器与服务器之间的双向实时通信而设计:客户端通过一次 HTTP 升级握手把连接切换为 WebSocket,此后双方可以在同一条 TCP 连接上随时互发数据帧。在代理领域,WebSocket 被广泛用作 VMess、VLESS 等协议的传输层(常写作 ws 传输):代理流量被封装成 WebSocket 帧,外观上与普通网页应用的实时流量一致,并且可以经由 CDN 转发——既隐藏了服务器真实 IP,也让流量特征更接近正常 Web 通信。
因此,代理场景下的”WebSocket 中断”包含两层含义:一是用户正在使用的应用(会议、消息推送、基于 WebSocket 的终端)自身的长连接断开;二是代理隧道使用的 ws 传输本身断开。两者的成因高度相似,排查思路也可以互相借鉴。
一条长连接要穿过多少设备
从手机到目标服务器,一条 WebSocket 连接通常要经过:家庭路由器的 NAT、运营商级 NAT(CGNAT)、防火墙、可能存在的 CDN 边缘节点,以及代理服务器本身。每一个环节都为这条连接维护着状态表项,而状态表容量有限,设备必然为空闲连接设置回收策略。链路上任何一个环节丢弃了状态,连接就名存实亡——而 TCP 的设计决定了通信双方在下一次发送数据之前不会察觉。关于 TCP 连接为何”断了也不知道”,可参考 TCP 与 UDP 的区别。
中断的常见原因
中间设备的空闲超时
NAT 网关和防火墙通常在连接空闲数分钟后删除映射表项,部分激进的设备只保留 30–60 秒。CDN 对空闲连接同样有回收策略,常见的空闲超时在 60–100 秒量级。连接状态被回收后,客户端发出的下一个数据帧会被直接丢弃或收到 RST 复位,应用层此时才发现连接已死。
心跳缺失或间隔过长
如果应用或代理客户端没有定期发送心跳帧,连接在流量间歇期就处于”空闲”状态,恰好落入上述回收策略的范围。需要强调:心跳间隔大于链路上最短的空闲超时,效果等于没有心跳。
网络切换
手机在 Wi-Fi 与移动数据之间切换时,出口 IP 与端口全部改变,原有 TCP 连接必然中断,上层 WebSocket 只能重新建立。切换后若表现异常,还可能叠加两种网络本身的连通性差异,类似 Wi-Fi 正常但移动数据无法使用 中讨论的情形。
运营商对长连接的干扰
部分网络环境会对存活时间过长或特征可疑的加密长连接实施干扰,表现为连接在大致固定的时长后被重置。这类中断往往有规律——例如总在几分钟左右断开——与随机的网络抖动可以区分开。
服务端重启与 CDN 节点调度
代理服务器重启、CDN 边缘节点维护或调度切换,都会切断现存连接。这类中断的典型特征是大面积同时掉线、随后迅速恢复。
心跳保活机制如何工作
心跳的本质是用极小的代价维持链路上所有状态表项的活跃:一端每隔固定时间发送一个 ping 帧,对端回复 pong。WebSocket 协议原生定义了 ping/pong 控制帧;代理协议层面,客户端的 keepalive 参数以及 TCP 层的 SO_KEEPALIVE 选项也起类似作用。有效的心跳间隔必须小于链路上最短的空闲超时,实践中常取 30 秒左右。心跳同时兼任探活:连续多次收不到回应,客户端即可主动重连,而不是被动等待漫长的 TCP 超时。
对用户的实际表现与缓解方法
长连接中断的典型表现包括:会议或语音进行中突然掉线、SSH 会话挂起无响应、消息推送延迟到重新打开应用才集中涌入、网页显示”已连接”但内容停止更新。值得注意的是,这类问题发生时对节点做延迟测试往往结果正常,因为延迟测试新建的是短连接,与已有长连接的死活无关——这与延迟正常但网页打不开的排查思路相通:单项指标正常不代表链路各环节都正常。
可行的缓解方向:
- 在应用与客户端中开启或缩短心跳,例如 SSH 配置 ServerAliveInterval,代理客户端检查 ws 传输的 keepalive 设置。
- 重要会议或长任务期间固定使用一种网络接入,避免 Wi-Fi 与移动数据来回切换。
- 若某条线路的中断呈现固定周期,更换节点或改用不同传输方式的协议;基于 QUIC 的 Hysteria 2 支持连接迁移,对网络变化更宽容,各协议差异见四种主流协议对比。
- 走 CDN 的 ws 节点频繁掉线时,换用直连传输的节点做对照测试,即可判断问题是否出在 CDN 的空闲回收。
长连接的脆弱不是代理独有的问题,而是有状态网络设备的固有代价;代理只是让链路更长、环节更多。理解每一跳的超时行为,比反复更换节点更能从根源上减少中断。ChatGPT、Claude 等 AI 服务的流式响应正是典型的长连接场景,对应的选择要点见 ChatGPT / AI 工具机场推荐。
常见问题
为什么开着代理开会总是过一段时间就掉线?
会议使用的长连接可能被链路上的 NAT、防火墙或 CDN 当作空闲连接回收,也可能受运营商对长时间加密连接的干扰。如果掉线时间点有规律,优先怀疑空闲超时或干扰;可尝试更换节点、改用直连传输的节点,或换用基于 QUIC 的协议观察是否改善。
心跳间隔设置成多少比较合适?
心跳间隔必须小于链路上最短的空闲超时才有效。家用路由器、CGNAT、CDN 的空闲回收多在 60 秒到几分钟之间,部分严格环境只有 30 到 60 秒,因此实践中常取 30 秒左右。间隔过短会增加耗电和流量,过长则失去保活意义,可从 30 秒开始按实际掉线情况微调。
换协议能减少长连接中断吗?
有一定帮助但不是万能。基于 QUIC 的 Hysteria 2 支持连接迁移,对网络切换更友好;走 CDN 的 WebSocket 节点如果频繁被空闲回收,换成直连传输的节点可以排除 CDN 因素。但如果中断源于本地网络的 NAT 超时或运营商干扰,任何协议都需要配合心跳与重连机制。
相关阅读
TCP 与 UDP 的区别及其对连接体验的影响
解释 TCP 与 UDP 在可靠性、有序性、握手与拥塞控制上的核心差异,以及这些差异如何影响代理协议的速度与稳定性,并简述基于 UDP 的 QUIC。
节点有延迟但网页打不开是什么原因
延迟测试正常、数值也不高,浏览器却无法打开网页——这类问题多与出口 IP 被限制、DNS 解析、分流规则或系统代理有关。本文解释延迟测试的局限,并给出按顺序的排查方法,适合已有一定使用经验的用户。
Shadowsocks、Trojan、VLESS 和 Hysteria 2 对比
从传输基础、TLS 依赖、抗干扰思路、性能开销与客户端支持五个维度对比 Shadowsocks、Trojan、VLESS 与 Hysteria 2 四种代理协议,并按使用场景给出选择建议。