WebSocket卡在Pending,说明连接已发出但未收到101 Switching Protocols响应,问题出在握手链路——Nginx需关闭proxy_buffering、透传Upgrade/Connection头、调大proxy_read_timeout;后端则需确认WebSocket启用、Filter未拦截、证书匹配且请求抵达业务层。

WebSocket卡在Pending,基本可以确定:连接请求发出去了,但还没收到101 Switching Protocols响应——问题不在前端代码,而在握手链路某处被拦或延迟了。
为什么Nginx代理后WebSocket一直Pending
Nginx默认开启proxy_buffering on,它会攒够响应再发给客户端;而WebSocket握手必须**实时返回101状态码 + Upgrade: websocket + Connection: upgrade头**,缓冲一挡就卡死。
- 必须显式关闭缓冲:
proxy_buffering off - 必须透传升级头:
proxy_set_header Upgrade $http_upgrade和proxy_set_header Connection "upgrade" -
proxy_read_timeout不能用默认60秒——空闲时Nginx会主动断开,建议设为86400 - 如果启用了
proxy_cache,也得关掉,否则可能缓存101响应,导致后续连接复用错误结果
Tomcat或Spring Boot后端没响应101怎么办
绕过Nginx直连后端(比如curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" http://localhost:8080/ws),如果返回101,说明后端OK,问题纯属代理层;如果不返回,就得查后端。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- Spring Boot内嵌Tomcat默认不启用WebSocket支持,需确认是否加了
@EnableWebSocket或配置了ServletWebServerFactory - Filter(如Shiro、Spring Security)可能静默拦截
/ws路径——尤其开发环境有session、真机访问没session时容易中招 - 证书不匹配:HTTPS页面连
ws://会被浏览器直接拒绝;连wss://但服务端证书(如wss.pem)过期或域名不一致,也会卡在Pending - 检查后端日志:有没有打印出WebSocket握手的trace?没有,说明请求根本没进到业务层,大概率被网关、Filter或SSL终结点截断
如何快速定位Pending发生在哪一层
别猜,分段验证最可靠:
- 用
curl直连后端服务地址,看是否返回101—— 确认后端是否正常响应握手 - 在Nginx
access_log里加$status $upstream_http_upgrade,看日志里是否记录了101和websocket值;如果没有,说明上游没返回正确响应 - 浏览器Network面板点开Pending的WS请求,看Request Headers里是否有
Upgrade: websocket和Connection: Upgrade;Response Headers里有没有缺失关键头或状态码不是101 - 抓包验证(如
tcpdump -i any -w ws.pcap port 443),确认TCP连接是否建立、SYN/ACK是否完成、服务端是否真的发出了101响应包
真正棘手的点往往藏在细节里:比如Nginx配置改了但没重载,或者wss.pem证书更新了但EasyRTC服务里引用的还是旧路径;又比如proxy_set_header Connection "upgrade"少了引号,Nginx会当成变量解析失败却无报错——这些地方不打日志、不抓包,几乎没法发现。

















