使用SignalR實作Websocket實時資料傳輸時,前後端各自實作編碼後,無法将Websocket調試通過。沮喪之時,負責配置網絡代理的同僚說,網絡通路這塊使用了Ngnix代理設定,可能是造成Websocket連結不上的原因。查了下資料,果真如此。尼瑪又是個坑。
好吧,那就試圖在Ngnix中配置支援Websocket吧。
不過,首先要介紹下Websocket是個什麼東東。
WebSocket
WebSocket協定為建立用戶端和伺服器端需要實時雙向通訊的webapp提供了一個選擇。其為HTML5的一部分,WebSocket相較于原來開發這類app的方法來說,其能使開發更加地簡單。大部分現在的浏覽器都支援WebSocket,比如Firefox,IE,Chrome,Safari,Opera,并且越來越多的伺服器架構現在也同樣支援WebSocket。
在實際的生産環境中,要求多個WebSocket伺服器必須具有高性能和高可用,那麼WebSocket協定就需要一個負載均衡層,NGINX從1.3開始支援WebSocket,其可以作為一個反向代理和為WebSocket程式做負載均衡。
WebSocket協定不同于HTTP協定,但是WebSocket握手是通過HTTP來完成的,使用HTTP的Upgrade設施來更新連接配接從HTTP到WebSocket。這個允許WebSocket程式能夠更簡單地融入現有的基礎設施。比如,WebSocket程式可以使用80和443标準的HTTP端口,進而允許使用存在的防火牆政策。
一個WebSocket程式持有一個長時間運作的在用戶端和伺服器端之間打開的連接配接,促進實時應用程式的開發(這個翻譯有問題)。被用來更新連接配接從HTTP到WebSocket的HTTP Upgrade機制使用Upgrade和Connection頭部來完成。在反向代理伺服器支援WebSocket中,需要面臨一些挑戰。第一個是WebSocket是一個hop-by-hop協定,是以當代理伺服器攔截來至于客服端的一個Upgrade請求時,代理伺服器需要發送它自己的Upgrade請求給後端伺服器,包括一些合适的頭部。同樣,因為WebSocket是長時間存活,相反的,HTTP連接配接是典型的短連接配接,反向代理伺服器必須允許這些連接配接保持打開,而不是在它們看起來閑置時關閉它們。
而後,說下Ngnix中的配置。
nginx
NGINX通過允許一個在用戶端和後端伺服器之間建立的隧道來支援WebSocket。為了NGINX發送來至于用戶端Upgrade請求到後端伺服器,Upgrade和Connection頭部必須被設定明确。So,
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
...
location /chat/ {
proxy_pass http://backend;
// Add this:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
參考自:https://nginx.org/en/docs/http/websocket.html
墨匠