今天SignalR部署在測試環境服務器前端出現沒法鏈接,前端報錯以下:前端
failed: Error during WebSocket handshake: Unexpected response code: 200nginx
Failed to start the transport 'WebSockets': nullweb
SignalR地址直接報錯404後端
而後查看服務器端是否有什麼問題,服務器端也有報錯以下api
Microsoft.AspNetCore.SignalR.HubConnectionContext - Failed connection handshake.服務器
看前端報錯看像是WebSocket問題,由於SignalR本質仍是經過WebSocket來實現通訊的,根據錯誤像是服務器不支持WebSocket,咱們是使用的Nginx作代理的時候默認配置不支持WebSocket。須要修改代理設置,須要改代理請求頭的設置。websocket
主要修改以下,在location節點下面新增。session
文末有完整的nginx配置實例可複製。socket
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_key cert/_.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 http://192.168.0.28:8080; proxy_set_header Host $http_host; } #Signal代理 location /SignalR { proxy_pass http://192.168.0.28:8080; #啓用http長鏈接支持websocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }