1. 程式人生 > >nginx為WebSocket做反向代理,WebSocket伺服器連線302

nginx為WebSocket做反向代理,WebSocket伺服器連線302

對於企業生產用途,需要多個WebSocket伺服器來實現效能和高可用性,需要了解WebSocket協議的負載平衡層,NGINX自1.3版本起支援WebSocket,並可作為反向代理,並進行WebSocket的負載平衡應用。(所有版本的NGINX Plus也支援WebSocket。)

檢視關於NGINX可擴充套件性的最新效能測試,以負載平衡WebSocket連線。

WebSocket協議與HTTP協議不同,但WebSocket握手與HTTP相容,使用HTTP升級工具將連線從HTTP升級到WebSocket。這允許WebSocket應用程式更容易地適應現有的基礎架構。例如,WebSocket應用程式可以使用標準HTTP埠80和443,從而允許使用現有的防火牆規則。

WebSocket應用程式可以在客戶端和伺服器之間保持長時間執行的連線,從而有助於開發實時應用程式。用於將連線從HTTP升級到WebSocket的HTTP升級機制使用Upgrade和Connection頭。反向代理伺服器在支援WebSocket時面臨一些挑戰。一個是WebSocket是一個逐跳協議,因此當代理伺服器攔截客戶端的升級請求時,需要向後端伺服器傳送自己的升級請求,包括相應的標頭檔案。此外,由於WebSocket連線長期存在,與HTTP使用的典型短期連線相反,反向代理需要允許這些連線保持開啟狀態,而不是關閉它們,因為它們似乎處於空閒狀態。

允許在客戶機和後端伺服器之間建立隧道,NGINX支援WebSocket。對於NGINX將升級請求從客戶端傳送到後臺伺服器,必須明確設定Upgrade和Connection標題,如下例所示:

location /wsapp/ {  proxy_pass http://wsbackend;  proxy_http_version 1.1;  proxy_set_header Upgrade $http_upgrade;  proxy_set_header Connection “upgrade”;  }  一旦完成,NGINX將此處理為WebSocket連線。

NGINX Websocket示例

這是一個現場示例,顯示NGINX作為WebSocket代理。此示例使用ws,一種基於Node.js的WebSocket實現。NGINX作為使用ws和Node.js的簡單WebSocket應用程式的反向代理。這些說明已經通過Ubuntu 13.10和CentOS 6.5進行了測試,但可能需要針對其他作業系統和版本進行調整。對於此示例,WebSocket伺服器的IP地址為192.168.100.10,NGINX伺服器的IP地址為192.168.100.20。

如果您尚未安裝Node.js和npm,請執行以下命令:

對於Debian和Ubuntu:

$ sudo apt-get install nodejs npm  對於RHEL和CentOS:

$ sudo yum install nodejs npm  Node.js安裝nodejs在Ubuntu和nodeCentOS上。本例使用node,所以在Ubuntu上,我們需要從建立符號連結nodejs到node:

ln−s/usr/bin/nodejs/usr/local/bin/node要安裝ws,請執行以下命令:ln−s/usr/bin/nodejs/usr/local/bin/node要安裝ws,請執行以下命令: sudo npm install ws  注意:如果您收到錯誤訊息:“錯誤:無法從登錄檔中獲取:ws”,請執行以下命令來解決問題:

$ sudo npm config set registry http://registry.npmjs.org/  然後sudo npm install ws再次執行命令。

ws隨我們將用於我們的客戶端的程式/ root / node_modules / ws / bin / wscat一起提供,但是我們需要建立一個作為伺服器的程式。建立一個名為server.js的檔案,其中包含以下內容:

console.log(“Server started”);  var Msg = ”;  var WebSocketServer = require(‘ws’).Server  , wss = new WebSocketServer({port: 8010});  wss.on(‘connection’, function(ws) {  ws.on(‘message’, function(message) {  console.log(‘Received from client: %s’, message);  ws.send(‘Server received from client: ’ + message);  });  });  要執行伺服器程式,請執行以下命令:  $ node server.js  伺服器列印初始”Server started”訊息,然後在埠8010上偵聽,等待客戶端連線到它。當它收到一個客戶端請求時,它迴應它,併發送一個訊息回到客戶端包含它收到的訊息。要使NGINX代理這些請求,我們建立以下配置:

http {  map httpupgradehttpupgradeconnection_upgrade {  default upgrade;  ” close;  }

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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

}  NGINX偵聽埠8020,並向後端WebSocket伺服器傳送代理請求。該proxy_set_header指令使NGINX妥善處理WebSocket協議。

要測試伺服器,我們執行wscat作為我們的客戶端:

$ /root/node_modules/ws/bin/wscat –connect ws://192.168.100.20:8020  wscat通過NGINX代理連線到WebSocket伺服器。當您鍵入wscat的訊息以傳送到伺服器時,您會看到它在伺服器上回顯,然後客戶端上顯示來自伺服器的訊息。以下是一個示例互動:

伺服器: 客戶:  $ node server.js  Server started

wscat --connect ws://192.168.100.20:8020
  • 1

Connected (press CTRL+C to quit)

Hello  Received from client: Hello  < Server received from client: Hello  在這裡,我們看到客戶端和伺服器能夠通過作為代理的NGINX進行通訊,並且訊息可以繼續來回傳送,直到客戶端或伺服器斷開連線。讓NGINX正確處理WebSocket所需要的是正確設定標頭檔案來處理將連線從HTTP升級到WebSocket的升級請求。