Nginx服务器配置支持SignalR(WebSocket)

今天SignalR部署在测试环境服务器前端出现无法连接,前端报错如下:

failed: Error during WebSocket handshake: Unexpected response code: 200

Failed to start the transport WebSockets: null

SignalR地址直接报错404

然后查看服务器端是否有什么问题,服务器端也有报错如下

Microsoft.AspNetCore.SignalR.HubConnectionContext - Failed connection handshake.

看前端报错看像是WebSocket问题,因为SignalR本质还是通过WebSocket来实现通信的,根据错误像是服务器不支持WebSocket,我们是使用的Nginx做代理的时候默认配置不支持WebSocket。需要修改代理设置,需要改代理请求头的设置。

主要修改如下,在location节点下面新增。

文末有完整的nginx配置实例可复制。

proxy_http_version 1.1

指定使用http版本,因为只有http1.1才支持长连接。

proxy_set_header Upgrade $http_upgrade

将客户端http请求头Upgrade 透传过来

roxy_set_header Connection“upgrade”

upgrade意思是告诉服务器使用最高版本协议进行通信。

默认roxy_set_header Connection这里如果不写的话,在htt1.0中Connection默认是close的,即连接请求完毕后就关闭。

以上归根到底都是基于http头进行设置修改,如果我们自己本身对http头有更多了解,还是有很大帮助的。

按照这个修改,然后重启Nginx。nginx –s reload。

再看前端signal发现连接成功

但是这个时候其他webapi接口无法请求了,swagger可以打开但是接口无法请求了报400

这个时候也想到了应该是Nginx问题,毕竟再没有修改Nginx的时候其他接口是可以使用的。当然如果SignalR和api业务服务器本来就是相互独立那么就不会存在这个情况,我的SignalR和业务服务接口都是在一起的。

原因就在于我们刚刚配置了Nginx代理时使用长连接,但是我们webapi其他接口都是短连接的。所以我们要将signal的连接代理和webapi其他接口的代理分开。

最后的设置如下

location 就是Nginx的路由匹配,这样添加后当我们请求url域名后面是SignalR则使用长连接进行代理转发了。location通常我们还回用于静态文件的代理,这样静态文件直接通过nginx就能返回到前端了。不需要请求到后端服务器。

本次完整的nginx配置如下

server{ listen 80; listen 443 ssl; #域名 server_name t-aabb.com; #https配置证书和ssl ssl_certificate cert/_.aabb.com.crt; ssl_certificate_keycert/_.aabb.com.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; client_max_body_size 100m;#后端服务代理 location / {proxy_pass :8080;proxy_set_header Host $http_host; } #Signal代理 location /SignalR {proxy_pass :8080; #启用http长连接支持websocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";} }

举报/反馈