Nginx 正确支持 WebSocket 的关键是防止断连发生,需确保握手返回 101 状态码、配置 proxy_http_version 1.1 和 upgrade 头、调大超时参数、禁用缓冲与压缩,并通过 101 响应头、错误日志及 curl 验证生效。

要让 Nginx 正确支持 WebSocket 长连接、避免断连,关键不是“处理断连状态码”,而是**防止断连发生**——因为 WebSocket 断连本身不会返回 HTTP 状态码(如 4xx/5xx),真正该关注的是握手阶段是否成功返回 101 Switching Protocols,以及连接建立后是否被中间层静默关闭。
必须确保 WebSocket 握手返回 101 状态码
WebSocket 连接能否建立,完全取决于初始 HTTP 升级请求是否成功响应 101。如果看到 200、403、502 或连接直接关闭,说明 Nginx 没有正确透传升级头或协议不匹配:
- proxy_http_version 1.1; —— 必须显式声明,HTTP/1.0 不支持 Upgrade 机制
-
proxy_set_header Upgrade $http_upgrade; —— 把客户端的
Upgrade: websocket原样传给后端 -
proxy_set_header Connection "upgrade"; —— 注意双引号,这是强制升级的关键指令,不能写成
Connection $connection或漏掉
长连接保活:超时设置要远大于心跳间隔
Nginx 默认 proxy_read_timeout 60s 是 WebSocket 断连最常见的原因。它不是返回错误码,而是主动关闭空闲 TCP 连接,前端表现为 onclose 触发且无明确错误信息:
- proxy_read_timeout 86400; —— 设为 24 小时(或至少是后端心跳间隔的 2–3 倍)
- proxy_send_timeout 86400; —— 防止大消息或后端响应延迟导致中断
- keepalive_timeout 86400; —— 保持客户端到 Nginx 的连接不被系统或负载均衡器切断
禁用干扰项:缓冲、压缩与隐式连接关闭
这些配置不会产生状态码,但会破坏 WebSocket 帧流,间接导致连接异常中断:
- proxy_buffering off; —— 避免 Nginx 缓存后端推送的 ping/pong 或业务帧,造成粘包或延迟
-
gzip off; 或确保
gzip_types不含application/json等 WebSocket 常用类型 —— 压缩可能破坏二进制帧边界 -
proxy_set_header Connection "keep-alive"; 在非 upgrade 场景下可用,但 WebSocket 路径中必须用
"upgrade",二者不可混用
验证是否真正生效的三个硬指标
不要只看连接“能连上”,要确认底层行为符合 WebSocket 规范:
- 浏览器 Network 面板中,WebSocket 请求的 Status 显示 101 Switching Protocols,且响应头含
Upgrade: websocket和Connection: upgrade - 执行
tail -f /var/log/nginx/error.log,搜索upstream prematurely closed connection—— 出现即说明后端连接已被提前释放,配置未起效 - 用
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" http://your-domain/ws/手动模拟握手,观察响应是否完整返回 101 及对应头











