通过nginx转发实现wss(websocket ssl)
WebSocket建立流程其实是:
Client
│
│ HTTP GET + Upgrade: websocket
▼
Nginx
│
│ HTTP/1.1 + Upgrade
▼
Backend WS Server
必须满足三个条件:
1.1HTTP/1.1
WebSocket 升级只在 HTTP/1.1 工作
proxy_http_version 1.1;
1.2Upgrade Header
客户端:
Upgrade: websocket
Connection: Upgrade
Nginx必须转发:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
你用了标准写法:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
这是 官方推荐写法 ✔
1.3长连接超时
WebSocket不是短连接。
默认 nginx:
proxy_read_timeout 60s
如果 60 秒没数据就断。
你设置:
proxy_read_timeout 300s;
proxy_send_timeout 300s;
5分钟 不过生产环境一般会更长。
二、配置文件优化
2.1upstream 建议加 keepalive
upstream ws {
server 172.x:8081;
keepalive 64;
}
这样 nginx 到后端不会频繁建 TCP。
2.2建议增加 Host 头
否则有些 WS 框架会校验 Host。
proxy_set_header Host $host;
2.3 建议增加 X-Forwarded-For
方便日志和风控。
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2.4 建议关闭 proxy_buffering
WebSocket不需要buffer。
proxy_buffering off;
否则会增加延迟。
三、推荐生产版配置
1 | map $http_upgrade $connection_upgrade { |
四、WebSocket完整流转架构
flowchart LR A[Client Browser / App] -->|wss| B[Nginx 8443] B -->|Upgrade websocket| C[Backend WS Service] C --> D[业务服务] B -.日志.-> E[ELK]
五、踩坑的点
你现在:
listen 8443 ssl http2;
HTTP/2 不支持 WebSocket Upgrade。但 nginx 会自动降级为 HTTP/1.1,所以通常 没问题。如果遇到 websocket handshake 失败,可以改成:
listen 8443 ssl;