必须配置proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade"三项协议升级指令,并设proxy_read_timeout和proxy_send_timeout为86400、proxy_buffering off、tcp_nodelay on,才能完成WebSocket握手并维持长连接。

要让 Nginx 通过 nginx.conf 正确代理 WebSocket 并完成握手,关键不是“开启支持”,而是**显式透传升级信号、禁用短连接默认行为、匹配长连接生命周期**。漏掉任意一项,浏览器发的是 Upgrade: websocket,后端收到的却是普通 HTTP 请求,返回 200 而非 101,握手直接失败。
必须写全的三项协议升级配置
WebSocket 握手本质是一次带特定头的 HTTP/1.1 请求,Nginx 默认不处理也不转发这些字段,必须手动补全:
-
proxy_http_version 1.1;:强制使用 HTTP/1.1,HTTP/1.0 不支持Upgrade机制,设成 1.0 或不写都会导致握手中断 -
proxy_set_header Upgrade $http_upgrade;:用变量传递,不能硬写"websocket";某些客户端(如 IoT 设备)可能发"mqtt"或"chat",硬编码会截断协议协商 -
proxy_set_header Connection "upgrade";:注意是带英文双引号的字符串"upgrade",不是$http_connection或$connection_upgrade;Connection 是逐跳头,不可继承,Nginx 必须主动设为upgrade才能触发后端协议切换
超时参数必须调大,否则连接静默断开
WebSocket 是长连接,Nginx 默认的 proxy_read_timeout 60 会让空闲 60 秒的连接被单方面关闭,客户端无错误提示,只看到“突然断开”:
-
proxy_read_timeout 86400;:建议设为 24 小时(86400 秒),适用于聊天、监控等允许长时间静默的场景 -
proxy_send_timeout 86400;:防止后端分片发送大消息或延迟响应 ping/pong 时被中途切断 - 不用调
keepalive_timeout:它只影响 HTTP 短连接复用,对 WebSocket 无效
location 块中还需补充的关键项
除核心三项外,以下配置能避免常见干扰:
-
proxy_buffering off;:禁用缓冲,避免 WebSocket 帧被缓存合并或延迟转发 -
tcp_nodelay on;:禁用 Nagle 算法,减少小包传输延迟,提升实时性 -
proxy_set_header Host $host;:确保后端能正确识别原始域名,尤其涉及多租户或虚拟主机时 - 若代理 WSS(
wss://),SSL 终止需在 Nginx 完成,且确认 CDN 或负载均衡器未剥离Upgrade和Connection头
附:最小可用 location 示例
将以下配置放入 server 块内对应路径(如 /ws/ 或 /):
location /ws/ {
proxy_pass http://backend_ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_buffering off;
tcp_nodelay on;
}
配置完成后 reload Nginx(nginx -s reload),再用浏览器开发者工具 Network 标签页确认 WebSocket 请求状态码是否为 101 Switching Protocols —— 这才是握手成功的唯一标志。


















