ASP.NET Core SignalR部署Ubuntu Nginx代理WebSocket握手异常求助
解决SignalR WebSocket握手失败(204状态码)的Nginx配置方案
嘿,我完全懂你遇到的糟心问题——本地和Windows IIS上跑都好好的,一到Linux的Nginx代理就卡壳,肯定是Nginx没正确处理WebSocket的升级请求。咱们一步步把它搞定:
首先,问题根源很明确:SignalR依赖WebSocket协议实现实时通信,但Nginx默认不会自动转发WebSocket的升级请求,导致握手阶段返回204(无内容)错误。你需要调整Nginx配置,让它支持WebSocket的完整握手流程。
第一步:添加全局WebSocket映射配置
先打开Nginx主配置文件(通常是/etc/nginx/nginx.conf),在http块内添加这段映射规则,用来动态处理WebSocket的Connection请求头:
map $http_upgrade $connection_upgrade { default upgrade; '' close; }
这段配置的作用是:当请求头里包含Upgrade字段时,自动把Connection头设为upgrade(配合WebSocket升级);如果没有Upgrade字段,就设为close,确保普通HTTP请求不受影响。
第二步:修改站点的Server配置
找到你的应用对应的Nginx站点配置文件(比如/etc/nginx/sites-available/devportal.vrweartek.com),更新location块的配置,确保包含以下关键设置:
server { listen 80; server_name devportal.vrweartek.com; location / { proxy_pass http://localhost:5000; # 这里替换成你的Kestrel实际监听端口 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; # 禁止缓存WebSocket的实时通信内容 proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } # 如果你的SignalR Hub有特定路径(比如/chat),也可以单独配置这个location进一步优化 # location /chat { # proxy_pass http://localhost:5000/chat; # proxy_http_version 1.1; # proxy_set_header Upgrade $http_upgrade; # proxy_set_header Connection $connection_upgrade; # proxy_cache_bypass $http_upgrade; # } }
这里几个核心配置必须注意:
proxy_http_version 1.1:WebSocket强制要求使用HTTP/1.1协议,Nginx默认是1.0,必须显式修改。proxy_set_header Upgrade $http_upgrade和proxy_set_header Connection $connection_upgrade:这两个头是WebSocket握手的核心,告诉Nginx把升级请求完整转发给后端的Kestrel服务。proxy_cache_bypass $http_upgrade:避免Nginx缓存WebSocket的实时消息,防止出现连接延迟或异常。
第三步:验证配置并重启Nginx
先检查配置有没有语法错误:
sudo nginx -t
如果输出显示test is successful,就重启Nginx让配置生效:
sudo systemctl restart nginx
额外检查点
- 确认你的Kestrel应用确实在监听
localhost:port,可以在服务器本地用curl http://localhost:port/chat测试Hub是否正常响应。 - 如果后续要切换到HTTPS(强烈推荐),记得把前端的
ws://改成wss://,上述WebSocket配置同样适用于HTTPS场景,只要Nginx的SSL证书配置正确即可。
这样调整后,外部机器通过域名访问时,Nginx就能正确转发WebSocket请求给SignalR,握手失败的问题应该就能彻底解决了!
内容的提问来源于stack exchange,提问作者Artyom
相关产品推荐
相关产品推荐

