要让nginx正确代理websocket长连接,必须在location块中同步配置协议升级(proxy_http_version 1.1、upgrade和connection头透传)、延长proxy_read_timeout与proxy_send_timeout至86400、关闭proxy_buffering和gzip,缺一不可。

要让 Nginx 正确代理 WebSocket 长连接,不能只调一个超时参数——必须同步处理协议升级、读写超时、缓冲控制三件事。掉线主因不是网络不稳,而是 Nginx 默认把 WebSocket 当成 60 秒就该关闭的普通 HTTP 请求来处理。
必须在 location 块里配齐协议升级头
WebSocket 握手依赖 HTTP/1.1 的 Upgrade 机制,缺一不可:
- proxy_http_version 1.1; —— HTTP/1.0 不支持协议升级,这行是前提
- proxy_set_header Upgrade $http_upgrade; —— 用变量透传原始值(如 websocket、mqtt),不能硬写 "websocket"
- proxy_set_header Connection "upgrade"; —— 注意双引号包裹的字面量 "upgrade",不是 $http_connection
这三行必须放在匹配 WebSocket 路径的 location /ws/ { } 或 location /signalr/ { } 块内,写在 server 或 http 块顶层无效。
读写超时要同步设大且留余量
默认 60 秒是“准时断连”的根源,两个超时必须同时调整:
- proxy_read_timeout 86400; —— 控制 Nginx 等待后端发数据的空闲时间,建议设为 24 小时,或至少 ≥ 前端心跳间隔 × 3(例如心跳 30 秒,则 ≥ 90)
- proxy_send_timeout 86400; —— 控制 Nginx 向客户端发送数据的连续等待时间,防止大消息或 pong 帧被中途掐断
不要设为 0:部分 Nginx 版本行为未定义,可能回退到默认值甚至崩溃。
关闭缓冲和压缩,避免帧结构被破坏
WebSocket 是流式双向通信,Nginx 默认启用的缓冲、压缩、缓存会合并、延迟或篡改帧,导致静默断连:
- proxy_buffering off; —— 必须在同一 location 块中禁用响应缓冲
- gzip off; 或确保 gzip_types 不包含 application/json、text/plain 等常用类型
- proxy_cache off; —— WebSocket 消息不可缓存,启用即引发连接失败
验证是否真正生效
重启 Nginx 后,不能只看前端“连上了”,要确认底层握手与链路行为正确:
- 浏览器 Network 面板中,WebSocket 请求响应状态码应为 101 Switching Protocols
- 检查 Nginx 错误日志,确认无 upstream prematurely closed connection 报错
- 用 curl 测试:curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" http://your-domain/ws,观察响应头和连接保持情况











