socket.io通訊原理

寫不好程式碼的格子襯衫發表於2019-04-26

socket.io是websocket的超集,在不支援websocket的情況下使用輪詢來進行相容。

概念

socket.io是一個跨瀏覽器支援WebSocket的實時通訊的JS,封裝了WebSocket和輪詢等方法,會根據情況選擇方法來進行通訊。支援客戶端&服務端,程式設計體驗統一。底層使用engine.io 封裝了一層協議。

資料編碼

engine.io使用websocket時有一套自己的ping/pong機制,使用的是opcode為0x1(Text)型別的資料幀,不是websocket協議規定的ping/pong型別的幀

engine.io的資料編碼分為Packet和Payload,其中 Packet是資料包,有7種型別:

  • 0 open:從服務端發出,標識一個新的傳輸方式已經開啟。
  • 1 close:請求關閉這條傳輸連線,但是它本身並不關閉這個連線。
  • 2 ping:客戶端週期性傳送ping,服務端響應pong。
  • 3 pong:服務端傳送。
  • 4 message:實際傳送的訊息。
  • 5 upgrade:在轉換transport前,engine.io會傳送探測包測試新的transport(如websocket)是否可用,如果OK,則客戶端會傳送一個upgrade訊息給服務端,服務端關閉老的transport然後切換到新的transport。
  • 6 noop:空運算元據包,客戶端收到noop訊息會將之前等待暫停的輪詢暫停,用於在接收到一個新的websocket強制一個新的輪詢週期。

Payload是指一系列繫結到一起的編碼後的Packet,它只用在poll中,websocket裡面使用websocket幀裡面的Payload欄位來傳輸資料。

// Payload格式
<length1>:<packet1>[<length2>:<packet2>[...]]
複製程式碼
/** polling模式返回值
 * 這裡總共有兩個packet
 * 第一個長度為96,packet型別為open
 * 第二個長度為2,packet型別為message
 **/
96:0{"sid":"WJT_1iJwliSggnDFAAAB","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000}2:40
複製程式碼

連結過程

socket.io與websocket的連結過程有所不同,多了相容模式以及心跳的模式。下圖的模式採用的是相容模式,transport: ['polling', 'websocket']

socket.io通訊原理

1.客戶端發起polling請求

socket.io通訊原理
2.服務端同意請求,返回 0

socket.io通訊原理
3.客戶端繼續發起polling,請求資料

socket.io通訊原理
4.客戶算髮起webscoket握手請求

5.服務端同意連結websocket,此時狀態碼為101

socket.io通訊原理
6.客戶端傳送websocket探測幀:2probe(ping)

7.服務端返回對應探測幀:3probe(pong)

8.客戶端傳送polling升級為websocket:5(upgrade)

socket.io通訊原理
9.服務端同意傳送noop訊息停止polling:6(noop)

socket.io通訊原理
10.websocket定時心跳(2/3)&收發資料(4)

socket.io通訊原理

transport: ['polling'] 的時候,只會使用polling來進行通訊

transport: ['websocket'] 的時候,只會使用websocket來進行通訊

transport: ['polling', 'websocket']兩者同時存在時,就會看瀏覽器相容性進行選擇

寫在最後

socket.io進行了相容性處理,使用起來也十分方便,不過要注意,當後端使用socket.io實現時,前端也需要使用socket.io來配合,因為需要相同的協議才能進行通訊。

相關文章