socket.io 工作流程
一、底层相关
socket.io 底层是engine.io,这个库实现了跨平台的双向通信。engine.io 使用了 websocket 和 XMLHttprequest(或JSONP)封装了自己的 socket协议,一个完整的 engine.io 包括多个 XHR 和 WebSocket 连接。
engine.io 协议通过一个 XHR 握手,前端发送一个 XHR,通知服务端要进行 XHR 长轮询了,服务端返回数据里包括 open 标志、sid 和 upgrades 字段。sid 相当于是 engine.io 的 SESSION ID,一次 engine.io 包含多个请求,后端又会同时连接多个 engine.io ,起身份的唯一标识;upgrades 一般为 websocket ,标识要把长轮询升级到 websocket。
engine.io 生命周期里,会间隔一定时间 ping - pong 一次,用来测试网络是否正常。
engine.io 主要处理服务端和客户端之间的各种传输和升级机制,还有断开检测功能。
engine.io-client 需要在 open 后才可以send,而 socket.io 则不需要,open 之前的 emit 的数据会在 open 之后再发送出去。
socket.io 服务端使用 ws 庫实现 websocket 协议, socket.io 服务启动时会先启动一个 ws 服务;在收到 upgrade 事件后,socket.io 会简单校验一下 websocket 相关请求,然后把请求交给 ws 服务进行处理。
socket.io 支持4种协议:WebSocket、htmlfile、xhr-polling 和 jsonp-polling 协议,它会自动根据浏览器选择合适的通讯方式,从而兼容大多数平台;
二、工作流程
在 Engine.io 连接的开始,服务器会发送一些数据信息:
{
'sid': "FDHSG-WEsdXXXXXXXXX",
//会话 ID。必须包含在后续 HTTP 请求的 sid 查询在数中;
'upgrades': ['websopcket'],
//升级数组包含服务器支持的所有更好的传输协议列表
'pingInterval': 25000, //值用于 heartbeat 机制
'pingTimeout': 20000 //值用于 heartbeat 机制
}
二、socket.io 特点
socket.io 有时候使用 WebSocket 作为传输,但它为每个数据包添加了额外的元数据,这也是为什么 WebSocket 客户端与 socket.io服务器无法相互成功连接。
socket.io 通过普通的 WebSocket 提供的功能有:
1、可靠性:如无法建立 WebSocket 连接,则回退到 HTTP 长轮询;
2、自动重连;
3、数据包缓冲:在默认情况下,socket 未连接时发出的任何事件都会被缓冲,在建立连接后再发送出去,但有时可能存在连接恢复时导致大量的事件触发,可以通过检测进行排除法触发对应事件;
if (socket.connected) {
socket.emit( /* ... */ );
} else {
// ...
}