WebSocket 與 Socket.IO

綜述:在做小程序和電視端互動項目時,也使用了socket.io十分重要的內容。

最近小組在做一個智慧交通的項目,其中有個 “分享屏幕” 的功能,即一個 client 能夠將自己當前的頁面分享到另外一個 client,針對這個需求,我們利用了 WebSocket 技術,具體說是 Socket.IO

1. 什麼是 WebSocket

提到 WebSocket,我首先會想到 “及時通訊” 和 “推送” 這類詞。在 WebSocket 以前,很多網站通過其他方式來推送信息,下面我們先看看以前的推送方式,這樣,有比較才能看出 WebSocket 的優勢。

1.1 (短)輪詢(Polling)

這種方式下,client 每隔一段時間都會向 server 發送 http 請求,服務器收到請求後,將最新的數據發回給 client。一開始必須通過提交表單的形式,這樣的後果就是傳輸很多冗餘的數據,浪費了帶寬。後來 Ajax 出現,減少了傳輸數據量。

如圖所示,在 client 向 server 發送一個請求活動結束後,server 中的數據發生了改變,所以 client 向 server 發送的第二次請求中,server 會將最新的數據返回給 client。

但這種方式也存在弊端。比如在某個時間段 server 沒有更新數據,但 client 仍然每隔一段時間發送請求來詢問,所以這段時間內的詢問都是無效的,這樣浪費了網絡帶寬。將發送請求的間隔時間加大會緩解這種浪費,但如果 server 更新數據很快時,這樣又不能滿足數據的實時性。

1.2 Comet

鑑於(短)輪詢的弊端,一種基於 HTTP 長連接的 “服務器推” 的技術被 hack 了出來,這種技術被命名爲 Comet。其與(短)輪詢主要區別就是,在輪詢方式下,要想取得數據,必須首先發送請求,在實時性要求較高的情況下,只能增加向 server 請求的頻率;而 Comet 則不同,client 與 server 端保持一個長連接,只有數據發生改變時,server 才主動將數據推送給 client。Comet 又可以被細分爲兩種實現方式,一種是長輪詢機制,一種是流技術。

1.2.1 長輪詢(Long-polling)

client 向 server 發出請求,server 接收到請求後,server 並不一定立即發送迴應給 client,而是看數據是否更新,如果數據已經更新了的話,那就立即將數據返回給 client;但如果數據沒有更新,那就把這個請求保持住,等待有新的數據到來時,纔將數據返回給 client。

當然了,如果 server 的數據長時間沒有更新,一段時間後,請求便會超時,client 收到超時信息後,再立即發送一個新的請求給 server。

如圖所示,在長輪詢機制下,client 向 server 發送了請求後,server會等數據更新完纔會將數據返回,而不是像(短)輪詢一樣不管數據有沒有更新然後立即返回。

這種方式也有弊端。當 server 向 client 發送數據後,必須等待下一次請求才能將新的數據發送出去,這樣 client 接收到新數據的間隔最短時間便是 2 * RTT(往返時間),這樣便無法應對 server 端數據更新頻率較快的情況。

1.2.2 流技術(Http Streaming)

流技術基於 Iframe。Iframe 是 HTML 標記,這個標記的 src 屬性會保持對指定 server 的長連接請求,server 就可以不斷地向 client 返回數據。

可以看出,流技術與長輪詢的區別是長輪詢本質上還是一種輪詢方式,只不過連接的時間有所增加,想要向 server 獲取新的數據,client 只能一遍遍的發送請求;而流技術是一直保持連接,不需要 client 請求,當數據發生改變時,server 自動的將數據發送給 client。

如圖所示,client 與 server 建立連接之後,便不會斷開。當數據發生變化,server 便將數據發送給 client。

但這種方式有一個明顯的不足之處,網頁會一直顯示未加載完成的狀態,雖然我沒有強迫症,但這點還是難以忍受。

1.3 WebSocket

寫到現在,大家會發現,前人推出那麼多的解決方案,想要解決的唯一的問題便是怎麼讓 server 將最新的數據以最快的速度發送給 client。但 HTTP 是個懶惰的協議,server 只有收到請求才會做出迴應,否則什麼事都不幹。因此,爲了徹底解決這個 server 主動向 client 發送數據的問題,W3C 在 HTML5 中提供了一種 client 與 server 間進行全雙工通訊的網絡技術 WebSocket。WebSocket 是一個全新的、獨立的協議,基於 TCP 協議,與 HTTP 協議兼容卻不會融入 HTTP 協議,僅僅作爲 HTML5 的一部分。

那 WebSocket 與 HTTP 什麼關係呢?簡單來說,WebSocket 是一種協議,是一種與 HTTP 同等的網絡協議,兩者都是應用層協議,都基於 TCP 協議。但是 WebSocket 是一種雙向通信協議,在建立連接之後,WebSocket 的 server 與 client 都能主動向對方發送或接收數據。同時,WebSocket 在建立連接時需要藉助 HTTP 協議,連接建立好了之後 client 與 server 之間的雙向通信就與 HTTP 無關了。

2. WebSocket 原理

相比於傳統 HTTP 的每次“請求-應答”都要 client 與 server 建立連接的模式,WebSocket 是一種長連接的模式。具體什麼意思呢?就是一旦 WebSocket 連接建立後,除非 client 或者 server 中有一端主動斷開連接,否則每次數據傳輸之前都不需要 HTTP 那樣請求數據。從上面的圖可以看出,client 第一次需要與 server 建立連接,當 server 確認連接之後,兩者便一直處於連接狀態。直到一方斷開連接,WebSocket 連接才斷開。

下面我們從報文層面談一下 WebSocket 與 HTTP 的差異。

首先,client 發起 WebSocket 連接,報文類似於 HTTP,但主要有幾點不一樣的地方:

  • "Upgrade: websocket": 表明這是一個 WebSocket 類型請求,意在告訴 server 需要將通信協議切換到 WebSocket

  • "Sec-WebSocket-Key: *": 是 client 發送的一個 base64 編碼的密文,要求 server 必須返回一個對應加密的 "Sec-WebSocket-Accept" 應答,否則 client 會拋出 "Error during WebSocket handshake" 錯誤,並關閉連接

server 收到報文後,如果支持 WebSocket 協議,那麼就會將自己的通信協議切換到 WebSocket,返回以下信息:

  • "HTTP/1.1 101 WebSocket Protocol Handshake":返回的狀態碼爲 101,表示同意 client 的協議轉換請求

  • "Upgrade: websocket"

  • "Connection: Upgrade"

  • "Sec-WebSocket-Accept: *"

  • ...

以上都是利用 HTTP 協議完成的。這樣,經過“請求-相應”的過程, server 與 client 的 WebSocket 連接握手成功,後續便可以進行 TCP 通訊了,也就沒有 HTTP 什麼事了。可以查閱WebSocket 協議棧瞭解 WebSocket 的 client 與 server 更詳細的交互數據格式。

3. WebSocket 與 Socket

網絡應用中,兩個應用程序同時需要向對方發送消息的能力(即全雙工通信),所利用到的技術就是 socket,其能夠提供端對端的通信。對於程序員而言,其需要在 A 端創建一個 socket 實例,併爲這個實例提供其所要連接的 B 端的 IP 地址和端口號,而在 B 端創建另一個 socket 實例,並且綁定本地端口號來進行監聽。當 A 和 B 建立連接後,雙方就建立了一個端對端的 TCP 連接,從而可以進行雙向通信。

WebSocekt 是 HTML5 規範中的一部分,其借鑑了 socket 的思想,爲 client 和 server 之間提供了類似的雙向通信機制。同時,WebSocket 又是一種新的應用層協議,包含一套標準的 API;而 socket 並不是一個協議,而是一組接口,其主要方便大家直接使用更底層的協議(比如 TCP 或 UDP)

4. 什麼是 Socket.IO

Socket.IO 是一個封裝了 Websocket、基於 Node 的 JavaScript 框架,包含 client 的 JavaScript 和 server 的 Node。其屏蔽了所有底層細節,讓頂層調用非常簡單。

另外,Socket.IO 還有一個非常重要的好處。其不僅支持 WebSocket,還支持許多種輪詢機制以及其他實時通信方式,並封裝了通用的接口。這些方式包含 Adobe Flash Socket、Ajax 長輪詢、Ajax multipart streaming 、持久 Iframe、JSONP 輪詢等。換句話說,當 Socket.IO 檢測到當前環境不支持 WebSocket 時,能夠自動地選擇最佳的方式來實現網絡的實時通信。

參考:

  1. Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE

  2. 微信公衆號: 【龍果】 --- 《WebSocket --web持久連接神器》

  3. WebSocket詳解(一):初步認識WebSocket技術

  4. Socket 與 WebSocket

  5. Differences between socket.io and websockets

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章