前言
最近項目中有端對端通信場景,實時性要求較高,考慮后選用了websocket 這一通信協議,本地做了個demo測試,跑的好好的,部署到測試服務器上,出現了客戶端連接服務端時提示404的問題,下面來看下。
正文
問題描述
本地客戶端程序簡單寫了個html,連接到服務端成功后的頁面如下
將服務端代碼部署到測試服務器上,想跟另一端做聯調測試,部署完后,本地客戶端再次連接,顯示異常:
看瀏覽器控制台報錯如下:
WebSocket connection to 'ws://ip:port/temperature/productWebSocket/9006' failed: Error during WebSocket handshake: Unexpected response code: 404
解決方法
修改服務器上nginx.conf 如下:
location /temperature{ proxy_pass http://127.0.0.1:port/temperature; # 增加Upgrade協議頭和Connection協議頭,使http連接升級到websocket連接 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
原因分析
我們都知道http協議使無狀態的,而websocket協議是建立一個tcp 長鏈接,而websocket協議的握手和http 是兼容的,它使用http 的Upgrade協議頭將Http 連接升級到WebSocket連接,這個特性使得websocket應用程序可以很容易地應用到現有的基礎設施。
大家可以看下http 和 websocket 通信協議在瀏覽器上的不同:
Http協議:
WebSocket協議:
WebSocket協議的握手和HTTP是兼容的,它使用HTTP的Upgrade協議頭將連接從HTTP連接升級到WebSocket連接。這個特性使得WebSocket應用程序可以很容易地應用到現有的基礎設施。
HTTP的Upgrade協議頭機制用於將連接從HTTP連接升級為WebSocket連接,Upgrade機制使用了Upgrade協議頭和Connection協議頭。反向代理服務器在支持WebSocket協議方面面臨着一些挑戰。挑戰之一是WebSocket是一個逐段轉發(hop-by-hop)協議,因此當代理服務器攔截到來自客戶端的Upgrade請求時,代理服務器需要將自己的Upgrade請求發送給后端服務器,包括合適的請求頭。而且,由於WebSocket連接是長連接,與傳統的HTTP端連接截然不同,故反向代理服務器還需要允許將這些連接處於打開狀態,而不能因為其空閑就關閉了連接。
參考鏈接
https://www.jb51.net/article/59847.htm