WebSocket连接卡在Pending,说明请求已发出但服务端未返回101 Switching Protocols响应,问题出在HTTP升级阶段;主因是Nginx未关闭proxy_buffering、未透传Upgrade/Connection头或proxy_read_timeout过短,或Spring Boot后端未正确注册WebSocket端点、被Filter拦截、缺少@EnableWebSocket等配置。

WebSocket连接卡在 Pending,基本可以确定:请求发出去了,但服务端没返回 101 Switching Protocols,握手被卡在 HTTP 升级阶段。这不是客户端代码写错了,而是中间链路或服务端没正确响应 Upgrade 请求。
为什么 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 秒,建议设为86400(24 小时),否则空闲连接会被主动断开 - 如果启用了
proxy_cache,也得关掉,否则可能缓存握手响应,导致后续连接复用错误结果
Spring Boot 后端返回 404 或 No adapter for handler 怎么办
这个报错不是 WebSocket 协议层问题,而是 Spring MVC 的 DispatcherServlet 在收到 Upgrade 请求后,找不到能处理 /ws/** 路径的 Handler —— 它把 WebSocket 握手当成了普通 HTTP 请求去匹配 @Controller,自然查无此人。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 确认已添加
@EnableWebSocket注解(Spring Boot 2.x)或配置了WebSocketConfigurationSupport(Spring Boot 3.x) - 检查依赖是否完整:
spring-boot-starter-websocket不能漏,且版本要与 Spring Boot 主版本对齐 - 确保 WebSocket 端点路径没被其他 Filter 拦截(比如 Shiro、Spring Security 的路径规则里排除了
/ws/**) - 内嵌 Tomcat 默认不启用 WebSocket 支持,需通过
ServletWebServerFactory显式启用
如何快速定位 Pending 发生在哪一层
别猜,分段验证:
- 绕过 Nginx,用
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" http://localhost:8080/ws直连后端——如果返回101,说明后端 OK,问题在代理层 - 在 Nginx access log 中加
$status $upstream_http_upgrade,看是否记录了101和websocket值;如果没有,说明 upstream 没返回正确响应 - 浏览器 Network 面板里点开 ws 请求 → Headers → 检查 Request Headers 里有没有
Upgrade: websocket,Response Headers 里有没有101和对应头——缺任何一项,就说明握手在那一层断了
最常被忽略的是:Nginx 配置改了但没重载(nginx -s reload),或者后端日志根本没打印握手 trace,说明请求甚至没进到业务层——这时候该查网关、SSL 终结点、防火墙策略,而不是调前端代码。

















