nginx 代理 websocket 二进制帧需关闭缓冲、透传 upgrade 和 connection 头、禁用压缩、调大超时,并通过抓包验证帧完整性,否则易导致截断、延迟或 1009 错误。

确保 WebSocket 协议升级完整透传
这是连接建立的前提,缺一不可:
- proxy_http_version 1.1 —— HTTP/1.0 不支持 Upgrade 机制,必须显式启用
- proxy_set_header Upgrade $http_upgrade —— 使用变量而非硬编码 "websocket",兼容各类客户端(如嵌入式设备可能发自定义协议名)
- proxy_set_header Connection "upgrade" —— 注意小写 upgrade 和英文双引号;写成 "Upgrade" 或空值会强制关闭连接
关闭所有可能干扰二进制流的代理行为
Nginx 若对原始字节流做缓存、压缩或重写,会破坏帧边界与时序:
- proxy_buffering off —— 防止攒帧再发,避免毫秒级毛刺或粘包
- proxy_buffer_size 4k —— 仅设最小缓冲区,不启用多级缓冲
- gzip off —— WebSocket 帧不能压缩,否则服务端解码失败
- proxy_set_header X-Accel-Buffering "no" —— 兼容部分 Nginx 版本,强制禁用加速缓冲
调大超时并跳过无意义的请求体解析
大二进制帧传输耗时长,Nginx 默认参数极易中断连接:
- proxy_read_timeout 86400 —— 覆盖长空闲或分片上传间隔(24 小时足够)
- proxy_send_timeout 86400 —— 避免大帧发送中途被切断
- client_max_body_size 0 —— 禁用请求体限制(WebSocket 不走 body 流程)
- client_body_timeout 0 —— 跳过对帧数据的无效读取等待
验证二进制帧是否真正透传
别依赖日志,用实际行为和抓包确认:
- 前端执行
ws.send(new Uint8Array([0x01, 0x02, 0xFF])),检查服务端是否收到原样字节数组 - Wireshark 过滤
websocket,确认 Frame Type 显示 BINARY,Payload 完全一致 - 若返回 400 或立即断连,优先排查 Upgrade/Connection 头是否丢失;若长度错乱或截断,重点查
proxy_buffering和proxy_buffer_size











