使用Nginx做WebSockets代理教程
WebSocket 協(xié)議提供了一種創(chuàng)建支持客戶端和服務(wù)端實時雙向通信Web應(yīng)用程序的方法。作為HTML5規(guī)范的一部分,WebSockets簡化了開發(fā)Web實時通信程序的難度。目前主流的瀏覽器都支持WebSockets,包括火狐、IE、Chrome、Safari以及Opera等,而且,越來越多的服務(wù)器應(yīng)用框架也開始支持WebSockets。
要在企業(yè)產(chǎn)品中使用WebSockets,為滿足高性能和高可用性,需要多個WebSocket服務(wù)器。負載均衡層需要支持WebSocket協(xié)議。Nginx從1.3版起就開始支持WebSocket協(xié)議,而且可以擔(dān)當WebSocket應(yīng)用程序的反向代理以及實現(xiàn)負載均衡。
WebSocket協(xié)議和HTTP協(xié)議不同,但是WebSocket協(xié)議的握手和HTTP是兼容的,它使用HTTP的Upgrade協(xié)議頭將連接從HTTP連接升級到WebSocket連接。這個特性使得WebSocket應(yīng)用程序可以很容易地應(yīng)用到現(xiàn)有的基礎(chǔ)設(shè)施。例如,WebSocket應(yīng)用可以使用標準的80和443 HTTP端口,因此可以通過現(xiàn)有的防火墻設(shè)施。
WebSockets應(yīng)用程序會在客戶端和服務(wù)器之間建立一個長連接,使得開發(fā)實時應(yīng)用很容易。HTTP的Upgrade協(xié)議頭機制用于將連接從HTTP連接升級到WebSocket連接,Upgrade機制使用了Upgrade協(xié)議頭和Connection協(xié)議頭。反向代理服務(wù)器在支持WebSocket協(xié)議方面面臨著一些挑戰(zhàn)。挑戰(zhàn)之一是WebSocket是一個逐段轉(zhuǎn)發(fā)(hop-by-hop)協(xié)議,因此當代理服務(wù)器攔截到來自客戶端的Upgrade請求時,代理服務(wù)器需要將自己的Upgrade請求發(fā)送給后端服務(wù)器,包括適合的請求頭。而且,由于WebSocket連接是長連接,與傳統(tǒng)的HTTP端連接截然不同,故反向代理服務(wù)器還需要允許這些連接處于打開(Open)狀態(tài),而不能因為其空閑就關(guān)閉了連接。
Nginx通過在客戶端和后端服務(wù)器之間建立隧道來支持WebSockets通信。為了讓Nginx可以將來自客戶端的Upgrade請求發(fā)送到后端服務(wù)器,Upgrade和Connection的頭信息必須被顯式的設(shè)置。如下所示:
location /wsapp/ {
proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
一旦我們完成以上設(shè)置,Nginx就可以處理WebSocket連接了。
Nginx WebSockets 實例
下面的例子講述了Nginx是如何為WebSocket做代理的。此例將使用ws模塊,它是基于node.js構(gòu)建的WebSocket實現(xiàn)。Nginx將擔(dān)當反向代理服務(wù)器,后端服務(wù)器是一個使用了ws和Node.js的簡單WebSockets應(yīng)用。例子使用的命令在Ubuntu 13.10和CentOS 6.5上測試通過,但對于其他操作系統(tǒng)或許需要稍作修改。就這個例子來說,WebSocket服務(wù)器的IP地址是192.168.100.10,Nginx服務(wù)器的IP地址是192.168.100.20。如果你還沒有安裝node.js和npm,你可以通過以下命令安裝:
對 Debian/Ubuntu 來說:
sudo apt-get install nodejs npm
對 RHEL/CentOS 來說:
sudo yum install nodejs npm
在Ubuntu上,node.js會被安裝為"nodejs",但在CentOS中被會安裝為"node"。我們在例子中統(tǒng)一使用"node",所以,我們會在Ubuntu上創(chuàng)建一個符號連接來允許我們使用“node”:
ln -s /usr/bin/nodejs /usr/local/bin/node
然后安裝 ws:
sudo npm install ws
注意:如果你得到了一個錯誤:“Error: failed to fetch from registry: ws” ,那么運行下面的命令應(yīng)該能解決這個問題:
sudo npm config set registry http://registry.npmjs.org/
接下來,你可以再次運行 sudo npm install ws
ws模塊來自/root/node_modules/ws/bin/wscat,我們會為客戶端使用它,但是我們需要創(chuàng)建一個程序來作為我們的服務(wù)器。將下面的代碼保存到一個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);
});
});
這個程序可以通過下面的命令執(zhí)行:
node server.js
該程序會輸出一條初始化消息“Server started”,之后監(jiān)聽8010端口,等待客戶端的連接。它會處理收到的所有請求,并且將接收到的消息輸出在控制臺,之后向客戶端返回一條包含該消息的消息。我們希望Nginx去代理客戶端的請求,可以通過下面的配置實現(xiàn):
map $http_upgrade $connection_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 "Upgrade";
}
}
上面的配置會使Nginx監(jiān)聽8020端口,并把任何接收到的請求轉(zhuǎn)發(fā)給后端的WebSocket服務(wù)器,讓后端服務(wù)器更好地處理WebSocket協(xié)議。我們可以使用wscat作為客戶端來測試一下:
/root/node_modules/ws/bin/wscat –connect ws://192.168.100.20:8020
上面的命令會通過Nginx反向代理服務(wù)器和后端WebSocket服務(wù)器建立連接,你可以向服務(wù)器發(fā)送任意消息,然后服務(wù)器會返回一條消息。每當你在客戶端發(fā)送一條消息,在后端服務(wù)器上能看到該消息的輸出,之后在客戶端會顯示一條來自服務(wù)端的消息。
這是一個交互示例:
Server: |
Client: |
$ node server.js |
|
Server started |
|
|
wscat –connect ws://192.168.100.20:8020 |
|
Connected (press CTRL+C to quit) |
|
> Hello |
Received from client: Hello |
|
|
< Server received from client: Hello |
由此我們可以看到客戶端與服務(wù)器能通過Nginx反向代理建立WebSockets通信,而且消息可以持續(xù)地進行雙向傳輸,直至客戶端或服務(wù)器斷開連接。為了讓Nginx能正確處理WebSocket連接,只需正確地設(shè)置消息頭來處理從HTTP連接升級到WebSocket連接的Upgrade請求。
相關(guān)文章
centos環(huán)境下nginx高可用集群的搭建指南
為了防止Nginx單點故障造成服務(wù)器癱瘓,本文介紹了Nginx實現(xiàn)高可用集群構(gòu)建,下面這篇文章主要給大家介紹了關(guān)于centos環(huán)境下nginx高可用集群的搭建指南,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-07-07Nginx性能優(yōu)化之Gzip壓縮設(shè)置詳解(最大程度提高頁面打開速度)
這篇文章主要介紹了Nginx性能優(yōu)化之Gzip壓縮設(shè)置詳解(最大程度提高頁面打開速度),需要的朋友可以參考下2022-01-01Nginx+SpringBoot實現(xiàn)負載均衡的示例
這篇文章主要介紹了Nginx優(yōu)雅的實現(xiàn)負載均衡,幫助大家更好的理解和使用nginx,感興趣的朋友可以了解下2020-10-10nginx結(jié)合openssl實現(xiàn)https的方法
這篇文章主要介紹了基于nginx結(jié)合openssl實現(xiàn)https的方法,準備工作大家需要安裝nginx服務(wù),具體操作過程跟隨小編一起看看吧2021-07-07使用Nginx創(chuàng)建臨時和永久重定向的具體示例
HTTP 重定向 是將一個域名或地址指向另一個的方法,有幾種不同類型的重定向,每種對客戶端瀏覽器意味著不同的事情,最常見的兩種類型是臨時重定向和永久重定向,本文給大家介紹了使用Nginx創(chuàng)建臨時和永久重定向的具體示例,需要的朋友可以參考下2024-07-07