引擎底层

Connection连接

  1. const client =io('https://myhost.com')

执行以下步骤:

  • 在客户端,创建一个engine.io-client实例
  • engine.io-client实例尝试建立轮询传输
  1. GET https://myhost.com/socket.io/?EIO=3&transport=polling&t=ML4jUwU&b64=1
  2. 如下:
  3. "EIO=3" # Engine.io协议的当前版本
  4. "transport=polling" # 正在建立的传输
  5. "t=ML4jUwU&b64=1" # 用于缓存总线的哈希时间戳
  • engine.io服务器响应为:
  1. {
  2. "type": "open",
  3. "data": {
  4. "sid": "36Yib8-rSutGQYLfAAAD", // 唯一会话ID
  5. "upgrades": ["websocket"], // 可能的运输升级列表
  6. "pingInterval": 25000, // 心跳机制的第一个参数
  7. "pingTimeout": 5000 // 心跳机制的第二个参数
  8. }
  9. }
  • 内容由engine.io-parser编码为:
  1. '96:0{"sid":"hLOEJXN07AE0GQCNAAAB","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000}2:40'
  2. 详细:
  3. "96" # 第一条消息的长度
  4. ":" # 长度和内容之间的分隔符
  5. "0" # "打开的"消息类型
  6. '{"sid":"hLOEJXN07AE0GQCNAAAB","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000}' # JSON编码的握手数据
  7. "2" # 第二条消息的长度
  8. ":" # 长度和内容之间的分隔符
  9. "4" # 消息类型
  10. "0" # socket.io协议中的"打开的"消息类型
  • 然后由客户端的engine.io-parser对内容进行解码。
  • engine.io-client级别发出open事件
  • socket.io-client级别发出connect事件

升级

一旦刷新了现有传输(XHR轮询)的所有缓冲区,就可以通过发送探测来测试升级。

  1. GET wss://myhost.com/socket.io/?EIO=3&transport=websocket&sid=36Yib8-rSutGQYLfAAAD
  2. 具体:
  3. "EIO=3" # 同样,当前版本的engine.io协议
  4. "transport=websocket" # 正在调查的新传输
  5. "sid=36Yib8-rSutGQYLfAAAD" # 唯一的会话id
  • 客户端在websocket帧中发送“ping”包,由engine.io-parser编码为2probe,其中2是“ping”消息类型。
  • 服务器响应一个“pong”包,编码为3probe,其中3是“pong”消息类型。
  • 在接收到“pong”包时,升级被认为是完成的,并且所有以下消息都通过新的传输。