1. 程式人生 > >websocket的那些事 - 初識

websocket的那些事 - 初識

簡介 

     WebSocket是一種在單個TCP連線上進行全雙工通訊的協議。WebSocket通訊協議於2011年被IETF定為標準RFC 6455,並由RFC7936補充規範。WebSocket API也被W3C定為標準。

       WebSocket使得客戶端和伺服器之間的資料交換變得更加簡單,允許服務端主動向客戶端推送資料。在WebSocket API中,瀏覽器和伺服器只需要完成一次握手,兩者之間就直接可以建立永續性的連線,並進行雙向資料傳輸。

出現背景

在websocket出現之前,實現伺服器向客戶端推送資訊,都是基於HTTP請求,實現技術有以下幾種:

輪詢方式:客戶端定時向服務端傳送ajax請求,伺服器接收到請求後馬上返回訊息並關閉連線。
優點:後端程式編寫比較容易。
缺點:TCP的建立和關閉操作浪費時間和頻寬,請求中有大半是無用,浪費頻寬和伺服器資源。
例項:適於小型應用。

長輪詢:客戶端向伺服器傳送Ajax請求,伺服器接到請求後hold住連線,直到有新訊息才返回響應資訊並關閉連線,客戶端處理完響應資訊後再向伺服器傳送新的請求。
優點:在無訊息的情況下不會頻繁的請求,耗費資源小。
缺點:伺服器hold連線會消耗資源,返回資料順序無保證,難於管理維護。
例項:WebQQ、Hi網頁版、Facebook IM。

長連線:在頁面裡嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設為對一個長連線的請求或是採用xhr請求,伺服器端就能源源不斷地往客戶端輸入資料。
優點:訊息即時到達,不發無用請求;管理起來也相對方便。
缺點:伺服器維護一個長連線會增加開銷,當客戶端越來越多的時候,server壓力大!
例項:Gmail聊天

Flash Socket:在頁面中內嵌入一個使用了Socket類的 Flash 程式JavaScript通過呼叫此Flash程式提供的Socket介面與伺服器端的Socket介面進行通訊,JavaScript在收到伺服器端傳送的資訊後控制頁面的顯示。
優點:實現真正的即時通訊,而不是偽即時。
缺點:客戶端必須安裝Flash外掛,移動端支援不好,IOS系統中沒有flash的存在;非HTTP協議,無法自動穿越防火牆。
例項:網路互動遊戲。

        在這種情況下,HTML5定義了WebSocket協議,能更好的節省伺服器資源和頻寬,並且能夠更實時地進行通訊。

Websocket使用ws或wss的統一資源標誌符,類似於HTTPS,其中wss表示在TLS之上的Websocket。如:

ws://example.com/wsapi
wss://secure.example.com/

Websocket使用和 HTTP 相同的 TCP ,可以繞過大多數防火牆的限制。預設情況下,Websocket協議使用80埠;執行在TLS之上時,預設使用443埠。

優點

  • 較少的控制開銷。在連線建立後,伺服器和客戶端之間交換資料時,用於協議控制的資料包頭部相對較小。在不包含擴充套件的情況下,對於伺服器到客戶端的內容,此頭部大小隻有2至10位元組(和資料包長度有關);對於客戶端到伺服器的內容,此頭部還需要加上額外的4位元組的掩碼。相對於HTTP請求每次都要攜帶完整的頭部,此項開銷顯著減少了。
  • 更強的實時性。由於協議是全雙工的,所以伺服器可以隨時主動給客戶端下發資料。相對於HTTP請求需要等待客戶端發起請求服務端才能響應,延遲明顯更少;即使是和Comet等類似的長輪詢比較,其也能在短時間內更多次地傳遞資料。
  • 保持連線狀態。於HTTP不同的是,Websocket需要先建立連線,這就使得其成為一種有狀態的協議,之後通訊時可以省略部分狀態資訊。而HTTP請求可能需要在每個請求都攜帶狀態資訊(如身份認證等)。
  • 更好的二進位制支援。Websocket定義了二進位制幀,相對HTTP,可以更輕鬆地處理二進位制內容。
  • 可以支援擴充套件。Websocket定義了擴充套件,使用者可以擴充套件協議、實現部分自定義的子協議。如部分瀏覽器支援壓縮等。
  • 更好的壓縮效果。相對於HTTP壓縮,Websocket在適當的擴充套件支援下,可以沿用之前內容的上下文,在傳遞類似的資料時,可以顯著地提高壓縮率。

握手協議

WebSocket 是獨立的、建立在 TCP 上的協議。

Websocket 通過 HTTP/1.1 協議的101狀態碼進行握手。

為了建立Websocket連線,需要通過瀏覽器發出請求,之後伺服器進行迴應,這個過程通常稱為“握手”(handshaking),互動如下圖所示:

互動請求頭例項

一個典型的Websocket握手請求如下:

客戶端請求

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

伺服器迴應

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/

欄位說明

  • Connection必須設定Upgrade,表示客戶端希望連線升級。
  • Upgrade欄位必須設定Websocket,表示希望升級到Websocket協議。
  • Sec-WebSocket-Key是隨機的字串,伺服器端會用這些資料來構造出一個SHA-1的資訊摘要。把“Sec-WebSocket-Key”加上一個特殊字串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然後計算SHA-1摘要,之後進行BASE-64編碼,將結果做為“Sec-WebSocket-Accept”頭的值,返回給客戶端。如此操作,可以儘量避免普通HTTP請求被誤認為Websocket協議。
  • Sec-WebSocket-Version 表示支援的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均應當棄用。
  • Origin欄位是可選的,通常用來表示在瀏覽器中發起此Websocket連線所在的頁面,類似於Referer。但是,與Referer不同的是,Origin只包含了協議和主機名稱。
  • 其他一些定義在HTTP協議中的欄位,如Cookie等,也可以在Websocket中使用。

支援瀏覽器

實現websocket的協議,瀏覽器扮演著一個很重要的角色。所有最新的瀏覽器支援最新規範(RFC 6455)的WebSocket協議。一個詳細的測試報告列出了這些瀏覽器支援的Websocket版本。

瀏覽器支援現狀

協議 釋出日期 IE Firefox(個人電腦) Firefox (Android) Chrome(個人電腦,手機) Safari(Mac, iOS) Opera(個人電腦,手機) Android瀏覽器
hixie-75 2010年2月4日       4 5.0.0    
hixie-76
hybi-00
2010年5月10日,
2010年5月23日
  4.0(已禁用)   6 5.0.1 11.00(已禁用)  
hybi-07 2011年4月22日   6[4]1          
hybi-10 2011年7月11日   7[5]1 7 14[6]      
13 RFC 6455 2011年12月 10[7] 11 11 16[8] 6 12.10[9] 4.4[10]

參考資料

WebSocket
https://zh.wikipedia.org/wiki/WebSocket

java WebSocket開發入門WebSocket

https://www.jianshu.com/p/d79bf8174196

WebSocket 教程

http://www.ruanyifeng.com/blog/2017/05/websocket.html