Nginx转发WebSocket到Node.js需三要素:协议升级(proxy_http_version 1.1、Upgrade $http_upgrade、Connection "upgrade")、长连接保活(proxy_read_timeout 86400、proxy_buffering off)、精准路径匹配(如location /ws/),缺一即断连。

Nginx 转发 WebSocket 到 Node.js 服务,关键在于正确处理协议升级、维持长连接、透传关键头部。它不是简单加个 proxy_pass 就能通的,必须显式支持 Upgrade 和 Connection 协议切换。
必须配置的 WebSocket 代理头
WebSocket 连接始于一次 HTTP Upgrade 请求,Nginx 必须识别并透传这个协商过程,否则握手失败,连接立即断开。
-
proxy_http_version 1.1;
HTTP/1.1 是 WebSocket 升级的前提(HTTP/1.0 不支持 Upgrade) -
proxy_set_header Upgrade $http_upgrade;
把客户端发来的Upgrade: websocket头原样转发给 Node.js -
proxy_set_header Connection "upgrade";
强制告诉后端:这不是普通 HTTP 请求,要切换协议
(注意:值必须是字面量"upgrade",不能写$http_connection,否则可能被覆盖为close)
完整 location 示例(推荐放在 server 块内)
location /ws/ {
proxy_pass http://node_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}其中 node_backend 是 upstream 定义的 Node.js 服务地址,例如:
upstream node_backend {
server 127.0.0.1:3000;
keepalive 32; # 启用连接池,提升复用率
}配合 Node.js 的注意事项
- Node.js 服务(如 Express +
ws库或 Socket.IO)需监听/ws/路径,且不依赖 cookie 或 session 初始化连接(因 Upgrade 请求不携带完整会话上下文) - 若需认证,建议在 WebSocket 握手 URL 中带 Token(如
ws://example.com/ws/?token=xxx),Node.js 在connection事件中解析并校验,避免延迟认证导致资源占用 - 禁用 Nginx 的
proxy_buffering on(默认开启),防止缓冲 WebSocket 帧;可显式设为proxy_buffering off;
常见失败原因排查
- 浏览器控制台报
Error during WebSocket handshake: Unexpected response code: 200
→ 检查是否漏了Upgrade和Connection头,或后端未返回101 Switching Protocols - 连接建立后几秒自动断开
→ 查看是否启用了proxy_read_timeout过短(WebSocket 无数据时也需保持),建议设为proxy_read_timeout 86400;(24小时)或更高 - 多实例部署下消息收发不一致
→ 确保负载均衡策略启用ip_hash或使用 sticky session,避免连接被分发到不同 Node 实例(尤其对非广播型 WebSocket 场景)
不复杂但容易忽略


















