配置Nginx支持WSS(WebSocket)

原文出處:http://colabug.com/229850.html

簡單瞭解一下 WebSocket

如今,不少網站爲了實現推送技術,所用的技術都是輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。html

在這種狀況下,HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。nginx

WebSocket一種在單個 TCP 鏈接上進行全雙工通信的協議。使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。web

以上信息摘自維基百科( 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/chat
wss://example.com/chat

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

若是你的網站是 HTTPS 協議的,那你就不能使用 ws:// 了,瀏覽器會 block 掉鏈接,和 HTTPS 下不容許 HTTP 請求同樣,以下圖:負載均衡

Mixed Content: The page at 'https://domain.com/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://x.x.x.x:xxxx/'. This request has been blocked; this endpoint must be available over WSS.

這種狀況,毫無疑問咱們就須要使用 wss:\ 安全協議了,咱們是否是簡單的把 ws:\ 改成 wss:\ 就好了?那試試唄。dom

改好了,報錯啦!!!

VM512:35 WebSocket connection to 'wss://IP地址:端口號/websocket' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR

很明顯 SSL 協議錯誤,說明就是證書問題了。記着,這時候咱們一直拿的是 IP地址 + 端口號 這種方式鏈接 WebSocket 的,這根本就沒有證書存在好麼,何況生成環境你也要用 IP地址 + 端口號 這種方式鏈接 WebSocket 嗎?確定不行阿,要用域名方式鏈接 WebSocket 阿。

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 狀態碼:

這樣就完成了,在 HTTPPS 下以域名方式鏈接 WebSocket ,能夠開心的玩耍了。

稍微解釋一下 Nginx 配置

Nginx 自從 1.3 版本就開始支持 WebSocket 了,而且能夠爲 WebSocket 應用程序作反向代理和負載均衡。

WebSocket 和 HTTP 協議不一樣,可是 WebSocket 中的握手和 HTTP 中的握手兼容,它使用 HTTP 中的 Upgrade 協議頭將鏈接從 HTTP 升級到 WebSocket,當客戶端發過來一個 Connection: Upgrade 請求頭時,Nginx 是不知道的,因此,當 Nginx 代理服務器攔截到一個客戶端發來的 Upgrade 請求時,須要顯式來設置 Connection 、 Upgrade 頭信息,並使用 101(交換協議)返回響應,在客戶端和代理服務器、後端服務器之間創建隧道來支持 WebSocket。

固然,還須要注意一下,WebSockets 仍然受到 Nginx 缺省爲60秒的 proxy_read_timeout 的影響。這意味着,若是你有一個程序使用了 WebSockets,但又可能超過60秒不發送任何數據的話,那你要麼須要增長超時時間,要麼實現一個 ping 的消息以保持聯繫。使用 ping 的解決方法有額外的好處,能夠發現鏈接是否被意外關閉。

更具體文檔詳見 Nginx 官方文檔: http://nginx.org/en/docs/http/websocket.html

相關文章
相關標籤/搜索