engine.io 原理详解

栏目: Html5 · 发布时间: 5年前

内容简介:因此,在介绍

socket.io 是基于Websocket 的Client-Server 实时通信库。

socket.io 底层是基于 engine.io 这个库。

因此,在介绍 socket.io 之前,先简单的介绍一些关于 engine.io 相关的知识,方便深入理解。

依赖关系详见:

2.Engine.io 基础

engine.iosocket.io 提供跨浏览器/跨设备的双向通信的底层库。 engine.io 使用了 WebsocketXHR 方式封装了一套 socket 协议。 在低版本的浏览器中,不支持 Websocket ,为了兼容使用长轮询( polling )替代。

相关源码如下:

3.Engine.io 工作流程

Client

import eio from './engine.io-client'

// 创建一个socket长连接
let socket = new eio.Socket('ws://localhost');
复制代码
engine.io 原理详解

根据流程图,可以看出:

  • 创建长连接的方式有三种: websocketxhrjsonp 。其中,后两种使用长轮询的方式进行模拟。
  • 所谓的长轮询是指,客户端发送一次 request ,当服务端有消息推送时会push一条 response 给客户端。客户端收到 response 后,会再次发送 request ,重复上述过程,直到其中一端主动断开连接为止。

4. webSocket 请求头信息

下图是建立成功的socket长连接:

engine.io 原理详解

参数说明

Request URL
Request Method
Status Code

RFC 7231 规范定义

规范解释: 当收到101请求状态码时,表明服务端理解并同意客户端请求,更改 Upgrade header字段。服务端也必须在 response 中,生成对应的 Upgrade 值。

  • Connection 设置 upgrade header,通知服务端,该 request 类型需要进行升级为 websocketupgrade_mechanism 规范
  • Host 服务端 hostname
  • Origin 客户端 hostname:port
  • Sec-WebSocket-Extensions 客户端向服务端发起请求扩展列表(list),供服务端选择并在响应中返回
  • Sec-WebSocket-Key 秘钥的值是通过规范中定义的算法进行计算得出,因此是不安全的,但是可以阻止一些误操作的websocket请求。
  • Sec-WebSocket-Protocol 指定有限使用的Websocket协议,可以是一个协议列表(list)。服务端在 response 中返回列表中支持的第一个值。
  • Sec-WebSocket-Version 指定通信时使用的Websocket协议版本。最新版本:13,历史版本
  • Upgrade 通知服务端,指定升级协议类型为 websocket

5.engine.io 协议解析

  • 客户端通过 engine.io 的url建立通信连接
  • 服务端在 response 中返回一个 open 的packet,JSON编码数据格式如下: 1. sid : session id ( String ) 2. upgrades : 传输类型( Array ) 3. pingTimeout : 服务端通信超时配置,客户端用于超时检测( Number ) 4. pingInterval : 服务端通信定时器配置,客户端用于超时检测( Number )
  • 收到客户端发送的 ping packets时,服务端必须定时发送 pong packets
  • 客户端与服务端可以随意交换 message pakcets
  • Polling 传输可以发送一个 close pakcet来关闭 socket ,因为他们可能会一直 openingclosing

6. URLs

engine.io URL的组成如下:

/engine.io/[?\<query string>]

  • engine.io : 只允许由库自身进行修改
  • query string : 可选字段,并提供了四个保留字段: 1. transport : 声明传输方式,可选值:< pollingwebsocket > 2. j : 如果传输方式为 polling ,但是需要 JSONP 的响应,则 j 必须设置为 JSONP 响应的 index 3. sid : 如果客户端已经分配了一个 session id ,则 sid 必须包含在 query string 中 4. b64 : 如果客户端不支持 XHR2 ,则必须在 query string 中加上 b64=1 标识,以通知服务端所有二进制数据应该进行base64编码

7. 编码方式

engine.io 有两种编码方式:

  • packet
  • payload

Packet

编码包可以是 UTF8二进制 数据,编码格式如下:

< 包类型id >[< data >]

例如:

2probe

包类型id(packet type id)是一个整型,具体含义如下:

  • 0 open 当打开一个新传输时,服务端检测并发送
  • 1 close 请求关闭传输,但不是主动断开连接
  • 2 ping 客户端发出,服务端应该返回包含相同数据的 pong packet进行应答
  • 3 pong 服务端发出,用以响应客户端的 ping packet
  • 4 message 真实数据,客户端和服务端应该调用回调中的 data
// 服务端发送 
send('4HelloWorld')
// 客户端接收数据并调用回调 
socket.on('message', function (data) { console.log(data); });
// 客户端发送 
send('4HelloWorld')
// 服务端接收数据并调用回调 
socket.on('message', function (data) { console.log(data); })
复制代码
  • 5 upgradeengine.io 切换传输之前,它会测试服务器和客户端是否可以通过此传输进行通信。如果此测试成功,客户端将发送升级数据包,请求服务器刷新旧传输上的缓存并切换到新传输。
  • 6 noop noop packet。主要用于在收到传入的 websocket 连接时强制轮询周期。
    2send
    3probe
    5
    

Payload

Payload 是绑定在一起的一系列编码分组。格式如下:

<length1>:<packet1>[<length2>:<packet2>[...]]
  • length : 表示 packet 的字符长度
  • packet : 真实数据包

Transports

engine.io 支持三种传输方式:

  • websocket
  • polling
    jsonp
    

Polling

长轮询传输包括客户端向服务器重复发出GET请求以获取数据,以及具有从客户端到服务器的有效负载的POST请求以发送数据。

XHR服务端必须支持 CORS

JSONP服务器实现必须使用有效的 JavaScript 进行响应。 URL包含必须在响应中使用的 query string 参数 jj 是整数。

JSONP包的格式:

___eio[< j > ](" <encoded payload> ");

例如:

___eio[4]("packet data");

原文地址


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

千夫所指

千夫所指

乔恩·罗森 / 王岑卉 / 九州出版社 / 2016-10-1 / CNY 42.80

编辑推荐: 《乌合之众》是为了跪舔权贵?《普通心理学》实验存在重大漏洞?《引爆点》的理论都是瞎掰的?社交网络时代《1984》预言的“老大哥”是否已经变成事实? 《纽约时报》年度十佳书 《GQ》杂志年度十佳书 《卫报》年度十佳书 《泰晤士报》年度十佳书 《经济学人》年度重推! 黑天鹅年度重点图书! 《乌合之众》是为了迎合权贵?《普通心理学》实验存在重大......一起来看看 《千夫所指》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具