1. 程式人生 > >使用nginx作為websocket的proxy server

使用nginx作為websocket的proxy server

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連線是典型的短連線,反向代理伺服器必須允許這些連線保持開啟,而不是在它們看起來閒置時關閉它們。

nginx

NGINX通過允許一個在客戶端和後端伺服器之間建立的隧道來支援WebSocket。為了NGINX傳送來至於客戶端Upgrade請求到後端伺服器,Upgrade和Connection頭部必須被設定明確。

示例,這個例子在我前面文章中使用過–chatRobot。上次是客戶端直接連的express程式,這裡我們使用nginx來做代理。

 upstream wsbackend {
        server 127.0.0.1:3000;
    }

    server {
        listen       8090;
        server_name  localhost;

        #charset koi8-r;
#access_log logs/host.access.log main; # location / { # root html; # index index.html index.htm; # } location / { proxy_pass http://wsbackend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }

我們將qt程式中的連結改一下

const char* server_url = "ws://localhost:8090";

我們的chatRobot還是一樣的可以執行。
這裡寫圖片描述

其實這只是一個簡單地接合nginx和nodejs的例子。
這裡我總結了幾點我們為什麼把nginx放在前面的。

  • nodejs適合做為restful api介面和動態的頁面生成,雖然也有靜態資源託管模組,但是會大幅度影響nodejs的效能,但是nginx適合處理靜態資源。所以讓它們做自己擅長的事。
  • 安全,直接在外網暴露nodejs會有很大的風險。
  • 卸HTTPS,nginx與客戶端連線加密,後端的nodejs和nginx處於內網環境下,可以不加密,這樣省去了nodejs卸https的負載。
  • nginx作為反向代理和負載均衡,方便後臺nodejs的橫向擴充套件。

使用nginx是為了更好地使用nodejs來提供服務。