聊天页面能打开但实时连接失败:该从哪里查
页面和聊天传输是不同的请求。先检查 WebSocket、事件流或长轮询,再把建立、投递和生命周期分开。
加载聊天页面之前先打开网络面板,然后找到承载消息的那个请求,而不是渲染页面骨架的那个。文档、脚本、登录时的交换以及聊天传输,都可能发往不同的主机。大多数说 VPN 弄坏聊天的报告,实际上描述的是这四个请求之一失败。按顺序观察,答案通常在前两分钟里就能看出来。
找到承载消息的那个请求
页面稳定后按类型筛选:WebSocket 会显示为独立条目,事件流保持打开且响应不断增长,长轮询按固定间隔重复。为承载更新的那个条目记录协议、主机、端口和状态。留意它是在登录之前还是之后开始的,因为认证之前打开的传输通常与之后打开的设计不同。阅读升级请求或所接受内容类型的请求头,它们能指出已部署页面实际选择了哪种传输。
旧论坛帖子描述的是产品多年前就不再使用的传输,所以要相信浏览器记录的内容,而不是文章。如果条目完全不存在,客户端代码可能从未尝试连接,这指向更早的脚本或配置故障。页面能加载只能证明文档到了,而这个区别决定了你是否真的在排查网络。
建立、投递和生命周期以不同方式失败
WebSocket 以 HTTP 升级开始,并用 101 状态作答,之后的一切都是分帧的消息,而不是抓取页面,RFC 6455 把这两个阶段明确分开。事件流以流式内容类型作答,并让响应体保持打开。两者都可能打不开、打开了却什么都没投递,或者打开、投递之后悄悄死掉。
wscat -c wss://chat.example.com/socket -H "Origin: https://chat.example.com"
curl -N -H "Accept: text/event-stream" https://chat.example.com/events
在动配置之前先抓住第一个有意义的失败,因为这三个时间点指向不同的层。如果握手从未完成,就与发往同一主机的普通 HTTPS 请求比较,看究竟有没有东西到达那里。如果完成了却没有消息,就在别人从另一个账号发送测试消息时观察帧或流式响应体。如果一开始能用然后停下,记录准确时间和关闭码,因为这一对能指出是哪一端放弃的。
1006 表示套接字在没有关闭帧的情况下关闭,中间设备或空闲超时从浏览器内部看就是这样。VPN 心跳不能证明内部的会话应用还活着。
实时主机是独立的目的地
聊天后端常常 运行在自己的主机名上,有时在另一个端口,或位于单独的证书之后。那个目的地需要自己的解析、路由和代理处理,而拆分隧道可能包含页面却排除套接字。从客户端机器解析实时主机名,确认它在那个网络上以你期望的地址作答。务必针对那个主机名检查证书链,因为覆盖站点的通配符并不总是覆盖套接字端点。
如果路径上有代理,确认它允许升级或长连接响应,而不是把它们缓冲下来。重写 HTML 的企业代理常常把 WebSocket 升级处理得很糟,结果页面能渲染,聊天却始终连不上。因此同一个产品的两个请求,并不是同一个主机的两个请求。
该修的是目的地址列表,而不是安全校验
修目的地列表属于路由改动,归路由的所有者管。放宽证书校验或去掉 Origin 头属于安全改动,归策略的所有者管,而那很少是排查工单的人。让连接看起来恢复正常的最快办法,通常也是让事故变得可能的最快办法。
改动之前先问应用所有者后端接受哪些来源,再把答案转给控制代理的人。如果证书错误只在隧道里出现,就检查那个拦截设备,而不是安装绕过。
留下足够交接的记录
有用的材料很短:页面 URL、实时端点、握手结果、首次失败的时间,以及是否尝试过重连。再加上 VPN 配置文件的名称和你所在的网络,任何人读了都能复现测试,不必再问六个问题。隐去 cookie、认证头和消息正文,并优先使用时间列的截图而不是完整导出归档。帧和网络归档可能包含私密消息和会话令牌,所以附加前先检查。
如果失败是静默关闭,要带上关闭码和它之前的空闲间隔,因为这一对通常能指出超时的归属。把记录交给应用或网关的所有者,而不是自己猜一个超时值。他们关于所支持 keepalive 行为的答复,才是关掉工单的答复。