nginx 透传 websocket 握手需三要素:动态透传 upgrade 头(proxy_set_header upgrade $http_upgrade)、显式设置 connection: upgrade、声明 proxy_http_version 1.1;三者须同在 location 块内且紧邻 proxy_pass,并配 proxy_read_timeout 等长连接参数。

要让 WebSocket 握手成功,Nginx 必须完整透传客户端发起的 HTTP 升级请求,其中 Upgrade 请求头不是可选项,而是强制要求——它必须原样转发,不能硬编码、不能遗漏、也不能放错位置。
必须用 $http_upgrade 动态透传
客户端握手时发送的请求头是 Upgrade: websocket(也可能是 mqtt 等其他合法值)。Nginx 默认不透传该字段,且若写成:
-
proxy_set_header Upgrade "websocket";—— 会覆盖原始值,导致非标准客户端(如 IoT 设备、自定义 SDK)握手失败 -
proxy_set_header Upgrade $http_upgrade;—— 才能准确捕获并转发客户端实际发送的内容,为空时也为空,安全可靠
必须配对设置 Connection 头
Upgrade 头只是“申请升级”,真正触发协议切换的是 Connection: upgrade。Nginx 默认可能把 Connection 改为 close 或 keep-alive,直接中断升级链路:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 必须显式写
proxy_set_header Connection "upgrade";(注意双引号包裹,不是变量) - 更稳妥的做法是配合
map指令做条件判断:map $http_upgrade $connection_upgrade { default upgrade; '' close; }
然后在 location 中使用proxy_set_header Connection $connection_upgrade;,兼顾普通 HTTP 和 WebSocket 流量
必须放在正确的配置位置
这三行关键指令必须同时满足上下文和位置要求,否则无效:
-
proxy_http_version 1.1;—— HTTP/1.0 不支持 Upgrade 机制,必须显式声明 - 全部配置必须写在
location块内,且紧邻proxy_pass后面 - 不要放在
http或server全局块里;推荐单独为 WebSocket 设路径,例如location /ws/ { ... } - 若用宝塔等可视化面板,需在反向代理「配置文件」区域手动追加,缩进与
proxy_pass对齐
配套超时与缓冲设置不可少
WebSocket 是长连接,空闲无数据属正常现象,Nginx 默认策略会主动断开:
-
proxy_read_timeout 86400;—— 防止心跳间隔超时断连(建议设为业务最大空闲时间的 2–3 倍) -
proxy_send_timeout 86400;—— 匹配发送侧,避免大消息或分片被截断 -
proxy_buffering off;—— 禁用响应缓冲,防止帧被暂存、延迟或粘包 -
proxy_set_header Host $host;和proxy_set_header X-Forwarded-Proto $scheme;—— 若后端依赖 Host 或协议判断,需一并透传










