Engine.io介紹
Socket.io是在engine.io的基礎上去實作的
Gitlab連結: Engine.IO: the realtime engine
engine.io
為socket.io
提供跨瀏覽器/跨設備的雙向通信的底層庫。engine.io
使用了Websocket
和XHR
方式封裝了一套socket
協議。在低版本的瀏覽器中,不支持Websocket,為了兼容使用長輪詢( polling )替代。
關於長輪詢可參考我的另一篇文章:WebSocket與Ajax的不同
過去WebSocket未出來時,許多聊天室使用的都是長輪詢的方式去實作,而engine.io則可依據客戶端環境兼容使用這兩種方式。
連線方式設定
在engine.io的constructor的參數裡有一個值是transports,這邊的polling指的就是長輪詢,預設值是會先用polling(http)去詢問,若回傳101 Switching Protocols
則才發起websocket連接
transports (<Array> String): transports to allow connections to (['polling', 'websocket']
)
請參考RFC 7231 規範
注意:這一點很重要,默認的,會使用長輪詢的連接方式作為第一手方案,隨後如果設備支持的話會升級到使用WebSocket,如果transports選項的值設置為['websocket']
,則意味著直接使用WebSocket方式建立連接,並且如果這一連接方式不能使用,也不會自動切換到備用的鏈接方案(polling),因此目前建議使用默認的設置即可,除非你明白確信使用場景和你想要做什麼。
Engine.io工作流程
編碼方式
engine.io有兩種編碼方式:
- packet:
例如:2probe
=> 2(packet type id)probe(data)
*0 open
當打開一個新傳輸時,服務端檢測並發送
*1 close
請求關閉傳輸,但不是主動斷開連接
*2 ping
客戶端發出,服務端應該返回包含相同數據的pongpacket進行應答
*3 pong
服務端發出,用以響應客戶端的pingpacket
*4 message
真實數據,客戶端和服務端應該調用回調中的data
*5 upgrade
*6 noop
/li> - payload: Payload是綁定在一起的一系列編碼分組,其格式是:<length1>:<packet1>[<length2>:<packet2>[…]]
例如:
97:0{“sid”:”Peed250dk55pprwgAAAA”,”upgrades”:[“websocket”],”pingInterval”:25000,”pingTimeout”:60000}2:40
傳輸方式
engine.io支持三種傳輸方式:
- websocket
- polling: jsonp, xhr