实时消息频繁断线怎么办?WebSocket 握手、关闭码与空闲超时
网页能加载,实时消息却频繁断线,先确认应用是否使用 WebSocket,再区分“握手没成功”和“建立后中断”。代理路径、登录状态、站点反向代理及空闲超时都可能影响连接,单看一个 1006 代码或一次网页测速,不能定位故障。
本文适用于网页通知、在线会话、协作页面等长连接场景。若问题是语音媒体连不上,应另查UDP 转发与媒体路径,不要把两种传输的问题混为一谈。
第一步:在浏览器里找到真实连接
以 Chrome 开发者工具为例,先打开 Network 面板,再刷新页面并触发发生问题的实时功能。筛选 WebSocket 类型,选中对应请求,在 Headers 中看目标地址与握手信息,在 Messages 中看收发消息和时间。
官方文档说明,Messages 表可以显示消息数据、长度和收发时间,也能区分部分控制帧。这里是在观察当前页面的连接,不需要自己拼一个测试地址。依据:DevTools 消息分析
记录目标主机时,注意它是否与网页主机不同。首页走代理,并不能替另一个消息域名的分流结果作证。应对照客户端中这一目标的连接记录,确认实际出站。
如果没有 WebSocket 请求,先核对是否已经触发相关功能、面板是否提前开始记录,以及应用是否使用事件流或轮询。不要仅因“消息是实时的”,就强行按 WebSocket 修复。
第二步:区分握手失败与连接后中断
HTTP/1.1 中,101 是升级成功的必要线索
传统 HTTP/1.1 WebSocket 握手使用升级流程,响应为 101 Switching Protocols,浏览器还要校验相关头部。返回普通网页的 200,或者跳转到登录页的响应,并不表示完成了这套握手。反过来,看到 101 也不证明后续消息会持续正常。依据:RFC 6455
检查失败时,保留原始 HTTP 状态、响应主机与控制台提示。证书或 TLS 错误应先按握手与信任链检查处理;不要通过关闭校验来制造“连接成功”。
不要把“必须看到 101”套到所有版本
HTTP/2 的 WebSocket 扩展采用扩展 CONNECT,RFC 8441 的成功示例返回 200,而不是上述 HTTP/1.1 升级形式。判断前先核对实际协商版本,不能把普通页面的 200 与扩展 CONNECT 的成功响应混为一谈。依据:RFC 8441
如果站点由你维护,还要分别检查客户端到边缘节点、反向代理到应用的协议;某一段支持,并不能证明每一段都配置正确。
第三步:正确解读关闭码
先看应用是否提供关闭码、关闭原因和事件时间;没有暴露这些信息时,就注明缺失,不凭感觉补一个原因。
| 观察到的代码 | 协议含义 | 下一步记录什么 |
|---|---|---|
| 1000 | 正常关闭 | 当时是否退出页面、完成会话或主动关闭 |
| 1006 | 异常结束的本地表示 | 握手结果、断开时间、此前最后一次收发 |
| 1008 | 与策略有关的关闭 | 应用给出的原因、服务端对应日志 |
| 1011 | 服务端遇到无法完成请求的异常 | 关联请求或会话标识及服务端错误 |
这些代码的定义见 RFC 6455 关闭码说明。其中 1006 是保留值,端点不能把它作为 Close 控制帧的状态码发送。因此,“浏览器显示 1006”不等于“服务器发送了一个说明代理被封的错误”。
浏览器标准也解释了,多种不同失败可能呈现为相同的 1006,页面脚本无法据此区分所有底层原因。还需要握手信息与两端日志来缩小范围。依据:WebSockets Standard
空闲一段时间才断,怎样查超时
把连接建立时间、最后一条收发消息的时间和断开时间分开记录。再比较“持续正常操作”和“暂时没有消息”两种情况;若只在后者出现相近间隔的断线,它是超时排查线索,但不是某台设备负责断开的证明。
以 nginx 的 HTTP/1.1 反向代理说明为例,升级所需的 Upgrade、Connection 头要正确传递;其文档还描述了后端连续 60 秒无数据时关闭连接的默认行为,可由 proxy_read_timeout 或合适的服务端 Ping 机制处理。这是特定代理的行为,不能据此宣布所有 WebSocket 都只有 60 秒寿命。依据:nginx WebSocket 代理
使用 CDN 的站点还应检查边缘层。Cloudflare 官方说明,发布新代码时的服务器重启可能终止已有 WebSocket 连接,也存在空闲关闭机制。这样的文档说明只能提供检查方向,不能替你的具体断线事件作证。依据:Cloudflare 技术说明
如果你只是访客,把时间和会话记录交给站点支持;如果你维护站点,再结合实际版本核对应用、反向代理和边缘层设置。只延长某一层超时,不一定覆盖整条路径。
心跳、重连与换节点各自能解决什么
心跳需要双方理解,不能随便发一个 ping 字符串
协议 Ping/Pong 与应用自己定义的心跳消息不是同一层。浏览器 WebSocket API 没有直接暴露协议 Ping/Pong 控制;发送文本 ping 是否有效,要看服务端是否定义了对应处理。不要向正在使用的业务会话随意注入测试消息。依据:WebSockets Standard 的 Ping/Pong 说明
重连成功不代表中断期间没有遗漏
重新连接后,还要按应用提供的历史记录、同步状态或消息序号核对连续性。若没有相应功能,至少记录断线前后的最后消息时间,不能把重新上线等同于消息全部补齐。
换节点只做一次单变量对照
保持同一浏览器、页面和操作,切换一个出站后重新建立连接。旧连接不会因为新节点名称出现,就自动成为有效的新测试样本。若原来使用规则分流,还要核对消息域名是否真的进入了所选出站,见代理接入与分流的区别。
把一次故障整理成可核查记录
| 项目 | 填写内容 |
|---|---|
| 环境 | 时间及时区、浏览器版本、接入方式与出站 |
| 目标 | 消息连接的主机和路径,隐藏令牌与查询凭据 |
| 握手 | HTTP 版本、方法、状态、控制台简短提示 |
| 时间线 | 建立、最后收发、关闭、重连的时间 |
| 关闭信息 | 代码、原因;无法取得则注明 |
| 对照 | 是否只在空闲时发生,本轮只改变了哪个条件 |
分享日志前隐藏 Cookie、认证信息和会话正文。只保留必要字段,也更容易让服务支持人员把同一次事件与服务端记录对上。
资料核对日期:2026-10-17。本文提供观察与排查方法,未对任何站点、节点或实时应用进行实测。
评论