Nginx 1.3.13 已經發布了,該版本支持 Connection: upgrade 和 Upgrade 頭,這就意味著支持WebSocket代理了.很多人都在等這個新特性以至于 “Nginx 支持 websockets 嗎?” 成為了 freenode上的#nginx頻道最常問的問題. 有了這種方式,讓我們來看看Nginx的WebSocket實現.
Nginx新添加的Websockets配置指令
文檔中提到的配置如下:(譯者注:原文中的鏈接其實不是文檔的鏈接.現在nginx的官方文檔中已經有websocket的說明了http://nginx.org/en/docs/http/websocket.html)
代碼如下:
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
這配置的確是相當簡單連配置HTTP的版本都是以前版本就支持的. 我們還可以稍微優化一下配置,通過創建一個鏈接的變量把proxy_set_headers放到一個公共的包含文件中,以此來提高通用性.
代碼如下:
map $http_connection $upgrade_requested {
default upgrade;
'' close;
}
這樣使得變量 $upgrade_requested 可以在 proxy_set_header Connection 里面使用,而且如果沒有 upgrade 的鏈接請求,則Conection這個頭會被設置為"",這樣就不會干擾普通的請求了.這樣做的好處是,如果你只使用HTTP/1.1代理,那么你不需要再另外配置一個location來專門處理WebSockets.
鏈接升級似乎沒有往后移植到穩定的版本中,因此如果你想要使用鏈接升級功能,你必須使用開發版本。感激的是nginx的開發版本并不意味著它不是運行穩定版,只是意味著API會變,在這種情況下只會影響模塊的編寫者。不要害怕安裝開發版本來嘗試這個新特征。
局限性:
到目前為止,在websocket的執行部署中有一些局限性:
客戶端必須制定鏈接升級
客戶端必須請求鏈接升級,否則nginx將會失敗。當前這個要求在代碼里列為要做的部分,因此我需要說它是怎么失敗的,但是我可以肯定的是它最后也會被執行,因此我不需要依賴它。這個約束對任何人來說不是個問題,只會在當模塊的編寫者或許想要應用連接升級到后端且本身處理響應的情況下才會是問題。
WebSockets 超時
WebSockets 仍然受到缺省為60秒的proxy_read_timeout 的影響。這意味著,如果你有一個程序使用了 WebSockets,但又可能超過60秒不發送任何數據的話,那你要么需要增加超時時間,要么實現一個 ping 的消息以保持聯系。使用 ping 的解決方法有額外的好處,可以發現連接是否被意外關閉。
Keep-Alive & WebSockets
Keep-alive pings 對上述超時問題無效,因為它們只是在 TCP 級別上發送空包。它們不向應用程序報告,所以應用程序也不響應它們,因此 proxy_read_timeout 仍然會觸發。
新聞熱點
疑難解答