socket.io通信原理

socket.io是websocket的超集,在不支持websocket的狀況下使用輪詢來進行兼容。前端

概念

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

數據編碼

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']websocket

1.客戶端發起polling請求socket

2.服務端贊成請求,返回 0

3.客戶端繼續發起polling,請求數據

4.客戶算髮起webscoket握手請求

5.服務端贊成連接websocket,此時狀態碼爲101oop

6.客戶端發送websocket探測幀:2probe(ping)

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

8.客戶端發送polling升級爲websocket:5(upgrade)編碼

9.服務端贊成發送noop消息中止polling:6(noop)

10.websocket定時心跳(2/3)&收發數據(4)

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

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

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

寫在最後

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

相關文章
相關標籤/搜索