websocket 在 nginx 代理下断连主因是默认 60 秒超时,需在 location 块中同时配置 proxy_read_timeout 和 proxy_send_timeout(建议均设为 86400)、proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade、proxy_set_header connection "upgrade",并确保 https 下证书有效且禁用 http/2。

WebSocket 连接在 Nginx 代理下断开,绝大多数情况不是后端问题,而是 Nginx 把它当普通 HTTP 请求处理了——默认 60 秒无数据就主动关掉。要让它稳定长连,关键不是“加超时”,而是覆盖 Nginx 对长连接的默认假设,尤其要管住两个时间:读超时和写超时。
必须设大的 proxy_read_timeout
这个参数控制 Nginx 等待后端发数据的空闲时间。WebSocket 没有“响应体”,只有持续帧流;一旦后端几秒没推消息(比如用户静默),Nginx 就会直接断连。
- 默认值是 60,这就是“准时 60 秒断开”的根源
- 不能设为 0(Nginx 不支持,会回退到 60)
- 推荐设为 86400(24 小时),或至少 ≥ 前端心跳间隔 × 2
- 必须放在
location块内,否则不生效
同步调大 proxy_send_timeout
只调大读超时不够。如果后端要发一个大消息、或分片发送、或响应延迟,Nginx 在往客户端写数据时也可能因超时中断连接。
- 默认也是 60 秒,同样会掐断 WebSocket 流
- 建议与
proxy_read_timeout设为相同值,比如 86400 - 它影响的是 Nginx 向客户端发送数据的连续等待时间
别漏掉协议升级相关的超时前提
超时参数再大,握手失败也白搭。这三个配置必须同时存在,且都在同一个 location 块里:
-
proxy_http_version 1.1;—— 否则 Upgrade 机制不触发 -
proxy_set_header Upgrade $http_upgrade;—— 用变量透传,不能硬写 "websocket" -
proxy_set_header Connection "upgrade";—— 注意是固定字符串 "upgrade",不是变量
HTTPS 下 wss 连接还要额外注意
wss 要求整条链路可信。如果 Nginx 终止 SSL 后代理明文 ws 到后端,但自身 HTTPS 配置不完整,浏览器会拒绝建立连接。
- 确保 server 块中配置了有效证书、密钥、
ssl_protocols TLSv1.2 TLSv1.3 - 禁用 HTTP/2(
http_v2 off或不启用),因为 HTTP/2 不支持 Upgrade 机制 - location 必须直接匹配路径(如
/ws/),避免 rewrite 改动请求头











