Nginx代理WebSocket

Nginx代理WebSocket

引言

聊天、实时推送、在线协作这类场景用WebSocket长连接。前端经过Nginx访问后端WS服务时,如果只按普通HTTP反代配置,握手会失败,因为WebSocket要先发起Upgrade协议升级,Nginx必须把升级头透传给后端。

WebSocket握手原理

客户端先发HTTP请求,带Upgrade: websocket和Connection: Upgrade头,后端同意后把HTTP协议升级成持久双向长连接。Nginx默认不透传这两个头,导致握手400。

标准代理配置

location /ws/ {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 3600s;
}
  • proxy_http_version 1.1:WS基于HTTP/1.1;
  • Upgrade $http_upgrade:透传客户端升级协议;
  • Connection "upgrade":标记连接升级;
  • read_timeout拉长:长连接默认60秒无数据会被Nginx断开。

用map统一处理

不同location可能同时有HTTP和WS,写map避免硬编码:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}
# location内
proxy_set_header Connection $connection_upgrade;

普通HTTP请求$http_upgrade为空时走close,WS请求走upgrade,一套配置兼容。

常见问题

  • 握手400/502:没加Upgrade和Connection头;
  • 连接几十秒自动断开:read_timeout太短,按需拉长或服务端发心跳;
  • wss(HTTPS)走Nginx终止TLS后,后端用ws即可;
  • 后端端口和proxy_pass写对,别漏http://。

注意事项

  • 长连接超时靠心跳和read_timeout共同维持;
  • 集群WS要配合粘性会话或后端共享状态,否则消息发不到正确连接;
  • HTTPS页面必须用wss://,浏览器会拦截混合内容;
  • 改配置nginx -t后reload。

总结

Nginx代理WebSocket核心是加proxy_http_version 1.1、透传Upgrade和Connection头、拉长read_timeout,用map兼容普通HTTP。握手失败先查这三个头,断线先查超时和心跳。


emer 发布于  2026-10-19 07:22 

Nginx配置websocket反向代理

前言

做实时聊天、推送、在线游戏,需要用 WebSocket。Nginx 当反向代理的时候,默认不支持 WebSocket 协议,需要额外配置。本文讲一下怎么配。

WebSocket 是什么

WebSocket 是一种全双工通信协议,浏览器和服务器建立连接后,可以一直保持连接,互相实时推送消息。

为什么需要特殊配置

普通 HTTP 请求是短连接,请求完就断了。WebSocket 是长连接,而且用的是 Upgrade 协议头。Nginx 默认的反向代理不支持这种升级,需要加特殊配置。

基础配置

location /ws/ {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

关键就是这三行:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

完整配置示例

server {
    listen       80;
    server_name  www.example.com;

    root  /var/www/html;
    index index.html;

    # WebSocket 代理
    location /ws/ {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 300s;
    }

    # 普通 HTTP 代理
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

超时配置

WebSocket 是长连接,默认超时时间短了会自动断开。

proxy_read_timeout 300s;
proxy_send_timeout 300s;

意思是:5分钟没有数据传输才断开。

常见坑

坑1:WebSocket 连接失败

前端连 WebSocket 一直失败。

原因: Nginx 没配 Upgrade 和 Connection 头。

解决: 加上那三行关键配置。

坑2:连接几秒就自动断了

连上了,过一会儿就断了。

原因: Nginx 默认超时时间太短(60秒)。

解决: 调大 proxy_read_timeout。

坑3:HTTPS 下 WebSocket 连不上

HTTP 下正常,HTTPS 下连不上。

原因: 前端用了 ws://,但网站是 https 的,浏览器不让。

解决: 前端用 wss://(加密的 WebSocket)。

坑4:连接数太多被拒

很多人同时在线,新的连接被拒了。

原因: Nginx 或后端服务器连接数限制。

解决: 调大 Nginx 和后端的连接数限制。

总结

WebSocket 代理就三行核心配置:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

记住: WebSocket 是长连接,记得调大超时时间,别让它自动断了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:48 
'); })();