售前咨询400-838-0503

WebSocket连接失败怎么办?

发布:2026-11-02 12:28

搜索全部帮助分类的文档

使用在线终端、实时聊天、监控面板等应用时,有时会遇到页面正常打开,但一直显示“连接中”“连接失败”或频繁掉线的情况。

这些功能可能使用WebSocket长连接。排查时需要区分:是连接一开始就没有建立,还是建立后又断开。本文以Linux服务器和Nginx常见的HTTP/1.1 Upgrade转发方式为例。

一、确认实际连接地址和报错

在浏览器中按F12打开开发者工具,进入“网络(Network)”,选择“WS”筛选项,然后重新触发连接。

记录请求地址、响应状态、发生时间,以及连接断开前是否收到过消息。

重点检查:

  • 域名、端口、路径和查询参数是否正确。

  • HTTPS页面是否使用wss://连接。

  • 接口是否需要登录、令牌或指定子协议。

  • 请求是否被重定向到了登录页或普通网页。

例如,页面地址为:

https://example.com

对应的WebSocket地址可能是:

wss://example.com/ws

/ws只是示例,必须使用应用实际提供的接口。

常见响应可以这样判断:

响应结果 优先检查
101 已返回协议升级响应,继续检查消息收发和业务鉴权
200 是否访问了普通页面,或没有进入升级处理流程
301、302 地址跳转、HTTPS识别或登录状态
400、426 握手参数、协议版本及升级请求头
401、403 登录凭据、Origin校验及访问控制
404 接口路径及代理路由
502、504 后端连接、服务状态及超时日志

以上是排查方向,具体原因仍需结合响应内容和服务端日志判断。

二、使用curl检查握手响应

使用curl测试WebSocket握手并查看101响应

在终端执行以下命令,可以辅助检查HTTP/1.1握手:

curl --http1.1 -i -N --max-time 8 \
  -H 'Connection: Upgrade' \
  -H 'Upgrade: websocket' \
  -H 'Sec-WebSocket-Version: 13' \
  -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \
  -H 'Origin: https://example.com' \
  https://example.com/ws

将域名、路径和Origin替换为实际值。Origin应对应发起连接的页面来源,包含协议、域名和必要的端口,不包含页面路径。

示例Key用于手工诊断,正式客户端会自动生成握手Key。需要Cookie、令牌或子协议的接口,还必须按应用要求补齐,不能直接用无登录信息的测试结果判断服务故障。

正常的升级响应通常包含:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

上述Accept值对应本例中的Key。完整握手还需要校验相关响应头。

如果先收到101,随后到第8秒提示curl超时,可能只是达到了命令设置的测试时限,不能据此认定服务掉线。

这条命令主要检查升级响应,并不完整模拟应用的WebSocket消息、登录流程或心跳。

三、检查Nginx是否转发升级请求头

查看Nginx读取的配置:

sudo nginx -T

找到实际域名和WebSocket请求匹配的配置位置。

以下示例假设接口路径为/ws,后端HTTP服务监听127.0.0.1:8080:

location = /ws {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;

    proxy_read_timeout 120s;
}

其中,Upgrade和Connection请求头需要明确传递给上游,后端才能按预期处理协议升级。

使用时注意:

  • 优先修改实际承接该接口的现有配置。

  • 保留原有请求头、鉴权及路由设置。

  • location = /ws是精确路径匹配,不匹配/ws/或其他路径。

  • 示例proxy_pass没有附加URI部分,不要随意增加或删除路径。

  • 不要直接用这一小段覆盖整份站点配置。

120s仅为读取超时的示例值,需要根据应用心跳和其他代理层的限制调整。

Nginx配置WebSocket反向代理及Upgrade请求头

四、确认后端服务和访问条件

如果代理配置看起来正常,继续检查实际后端。

查看本机监听情况:

sudo ss -lntp

确认后端服务已经启动,并且监听地址、端口与Nginx配置一致。

如果需要绕过前置代理测试,可复用第2节的握手命令,将目标改成实际HTTP后端地址,同时按应用要求设置Host、Origin和登录凭据。

测试应在Nginx能够访问后端的网络环境中进行。Docker容器内的127.0.0.1指向容器自身,不一定是宿主机或另一容器。

此外,还要检查:

检查位置 重点内容
应用配置 WebSocket功能是否启用,接口路径是否正确
登录与鉴权 Cookie、令牌、会话是否有效
Origin校验 实际页面来源是否在允许范围内
CDN、WAF或负载均衡 是否支持并允许该连接,是否有拦截记录
应用外部地址 是否正确识别公网域名和HTTPS访问方式

如果接口返回403,应先查看具体拒绝原因,再修正配置。

五、连接成功后掉线,检查心跳和超时

如果能够收到101,但连接过一段时间就断开,应重点检查心跳、空闲超时和应用日志。

查看Nginx错误日志:

sudo tail -n 50 /var/log/nginx/error.log

实际日志路径以站点配置为准。

如果出现类似提示:

upstream timed out (110: Connection timed out)
while proxying upgraded connection

说明连接升级后发生了上游超时,需要检查后端是否长时间没有发送数据。

Nginx的proxy_read_timeout限制的是两次读取上游数据之间的等待间隔,并不是WebSocket连接的总存活时间。

处理时建议:

  • 由应用实现有效的心跳及响应。

  • 心跳间隔小于连接路径上最短的空闲超时。

  • 同时核对CDN、负载均衡和应用自身的限制。

  • 检查后端是否重启、异常退出或主动关闭连接。

仅客户端持续发送消息,而后端完全没有返回数据,未必能避免Nginx的读取超时。

单纯把超时时间调得很大,也无法修复鉴权失败、程序崩溃或网络中断。

查看Nginx日志排查WebSocket连接建立后掉线

六、检查配置并验证实际功能

修改Nginx配置后,对于使用systemd管理、服务名为nginx的部署,执行:

sudo nginx -t && sudo systemctl reload nginx

配置检查通过后才会执行重载。面板安装、容器部署或自定义路径安装的Nginx,应使用对应实例的检查和重载方式。

随后重新打开应用,验证:

  1. 握手能够正常完成。

  2. 登录或设备认证成功。

  3. 实际消息能够双向收发。

  4. 连接能保持到原先容易掉线的时间点之后。

  5. 网络恢复后,应用能够按设计重新连接。

测试时同时观察浏览器和服务端日志,确认没有持续出现相同错误。

常见问题

1. 网站能打开,为什么WebSocket仍然失败?

普通页面请求与WebSocket升级请求的处理方式不同。首页正常,只能说明普通访问可用,不能证明升级请求头、接口路由和业务鉴权都正确。

2. curl返回101,为什么应用仍显示离线?

101只能说明服务返回了协议升级响应。应用可能还需要设备认证、指定子协议、首条登录消息或有效心跳,必须继续验证完整业务流程。

3. 使用WSS,后端也必须配置HTTPS吗?

不一定。常见部署由Nginx处理公网TLS,再通过受信任的内部网络连接HTTP后端。具体方式应根据网络环境和应用要求确定,公网入口的证书及域名仍需正确。

注意事项

修改前备份相关配置,排查时保留故障时间、请求路径和日志片段。需要登录的接口,应使用有效测试凭据,分享材料前隐藏Cookie、令牌和密码。

如果使用莱卡云服务器后仍无法定位问题,可提交工单,提供部署方式、WebSocket路径、握手响应、掉线时间及相关日志,便于进一步排查。

按文档操作后还是不行,把机器编号、出问题的时间点和现象截图一起提工单,能少来回一轮。

提交工单