nginx設置webscoket代理方法以及注意事項

為啥要寫這篇文章呢?

最近在做websocket的項目,踩到的坑做一個總結。

1.ws和wss問題

2.代理設置問題

3.域名開啟DNS后在使用代理出現的問題

1.配置Nginx支持WSS(WebSocket)

簡單了解一下 WebSocket

? WebSocket一種在單個 TCP 連接上進行全雙工通訊的協議。使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行雙向數據傳輸。

以上信息摘自維基百科(?https://zh.wikipedia.org/wiki/WebSocket?)

簡單點說,WebSocket 就是減小客戶端與服務器端建立連接的次數,減小系統資源開銷,只需要一次 HTTP 握手,整個通訊過程是建立在一次連接/狀態中,也就避免了HTTP的非狀態性,服務端會一直與客戶端保持連接,直到你關閉請求,同時由原本的客戶端主動詢問,轉換為服務器有信息的時候推送。當然,它還能做實時通信、更好的二進制支持、支持擴展、更好的壓縮效果等這些優點。

推薦一個知乎上叫 Ovear 的網友關于 WebSocket 原理的回答,嘻哈風格科普文,簡直不要更贊了!地址:?https://www.zhihu.com/question/20215561/answer/40316953

ws和wss是什么鬼?

Websocket使用?ws?或?wss?的統一資源標志符,類似于?HTTP?或?HTTPS?,其中?wss?表示在 TLS 之上的 Websocket ,相當于 HTTPS 了。如

ws://example.com/websocket

wss://example.com/websocket

默認情況下,Websocket 的 ws 協議使用 80 端口;運行在TLS之上時,wss 協議默認使用 443 端口。其實說白了,wss 就是 ws 基于 SSL 的安全傳輸,與 HTTPS 一樣樣的道理。

如果網站是https協議的話就不能使用ws://,會報協議錯誤,那怎么辦呢?

Nginx 配置域名支持 WSS

不用廢話,直接在配置 HTTPS 域名位置加入如下配置:

location?/websocket?{

????proxy_pass?http://backend;

????proxy_http_version?1.1;

????proxy_set_header?Upgrade?$http_upgrade;

????proxy_set_header?Connection?"upgrade";

}

接著拿域名再次連接試一下,不出意外會看 101 狀態碼,鏈接成功

2.Nginx實戰之反向代理WebSocket的配置實例

NGINX偵聽端口8020,并向后端WebSocket服務器發送代理請求。該proxy_set_header指令使NGINX妥善處理WebSocket協議。

ws.conf文件內容如下:

upstream websocket {

? ? server 192.168.100.10:8010;

}

server {

? ? listen 8020;

? ? location / {

? ? ? ? proxy_pass http://websocket;

? ? ? ? proxy_http_version 1.1;

? ? ? ? proxy_set_header Upgrade $http_upgrade;

? ? ? ? proxy_set_header Connection $connection_upgrade;

? ? }

}

WebSocket集群

在實際的生產環境中,要求多個WebSocket服務器必須具有高性能和高可用,那么WebSocket協議就需要一個負載均衡層,NGINX從1.3開始支持WebSocket,其可以作為一個反向代理和為WebSocket程序做負載均衡。

Nginx配置

注:看官方文檔說 Nginx 在 1.3 以后的版本才支持 websocket 反向代理,所以要想使用支持 websocket 的功能,必須升級到 1.3 以后的版本

NGINX通過允許一個在客戶端和后端服務器之間建立的隧道來支持WebSocket。為了NGINX發送來至于客戶端Upgrade請求到后端服務器,Upgrade和Connection頭部必須被設置明確。

upstream wsbackend {

? server 127.0.0.1:8080;

? server 127.0.0.1:8081;

}

server {

? listen? 80;

? server_name ws.52itstyle.com;

? location / {

? proxy_pass http://wsbackend;? proxy_http_version 1.1;

? proxy_set_header Upgrade $http_upgrade;

? proxy_set_header Connection "upgrade";

? }

}

前端配置:

$(function(){

socket.init();

});//Nginx反向代理實現websocketvar basePath = "ws://ws.52itstyle.com//acts_competition/";

socket = {

webSocket : "",

init : function() {

? if ('WebSocket' in window) {

? webSocket = new WebSocket(basePath+'webSocketServer');

? }

? else if ('MozWebSocket' in window) {

? webSocket = new MozWebSocket(basePath+"webSocketServer");

? }

? else {

? webSocket = new SockJS(basePath+"sockjs/webSocketServer");

? }

? webSocket.onerror = function(event) {

? //alert("websockt連接發生錯誤,請刷新頁面重試!")? };

? webSocket.onopen = function(event) {

? };

? webSocket.onmessage = function(event) {

? ? };

},

sendData : function(data) {

? webSocket.send(data);

},

}

最后,重啟下Nginx即可。

反向代理服務器在支持WebSocket時面臨的挑戰

WebSocket是端對端的,所以當一個代理服務器從客戶端攔截一個Upgrade請求,它需要去發送它自己的Upgrade請求到后端服務器,也包括合適的頭。

因為WebSocket是一個長連接,不像HTTP那樣是典型的短連接,所以反向代理服務器需要允許連接保持著打開,而不是在它們看起來空閑時就將它們關閉。

3.使用CDN加速后,websocket對象無法訪問

很簡單的原因,CDN加速的是靜態資源。

目前CDN還不支持websocket,建議將這類動態內容用一個單獨的域名拆出來單獨訪問,不使用CDN訪問。

使用阿里云的全站加速

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容