大家参与的项目里多少都会有web server与browser需要长连接互联的场景,当然我也是,之前没有进行太多方案的调研(比如深入理解通信协议和通用的一些解决方案),所以websocket就不假思索地直接用了,包括去年写的框架xframe里也是直接嵌入了官方websocket的library来实现的。
两周前遇到个场景,前端大佬提需求说能否支持socket.io,之前写的websocket的server组件不能用,当然是欣然答应,花了半天的时间重写了之前的websocket server支持socket.io的协议。但是为什么socketio不能兼容websocket呢?作为一名合格的工程师,不能知其然而不知其所以然,websocket是什么,它与socket.io有什么区别呢?他们又分别适合怎样的场景?为什么有了websocket还需要有socket.io?
于是花了几天时间(工作之余)研究下websocket的RFC6455上的定义,撸一遍golang版websocket的源码实现,比对比对Socket.IO。
本文介绍内容大致如下:
- weboscket
- weboscket握手机制细节
- websocket数据帧
- websocket代码分析
- socket.io
- socket.io特性介绍
- socket.io握手机制
- websocket与socket.io使用场景
Websocket
Websocket是全双工的基于TCP层的通信协议,为浏览器及网站服务器提供处理流式推送消息的方式。它不同于HTTP协议,但仍依赖HTTP的Upgrade头部进行协议的转换。
Websocket Handshake
websocket协议通信分为两个部分,先是握手,再是数据传输。
如下就是一个基本的websocket握手的请求与回包。
websocket handshake请求
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
websocket handshake返回
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
websocket消息根据RFC6455统称为"messages", 一个message可以由多个frame构成,其中frame可以为文本数据,二进制数据或者控制帧等,websocket官方有6种类型并预留了10种类型用于未来的扩展。
Websocket协议中如何确保客户端与服务端接收到握手请求呢?
这里就要说到HTTP的两个头部字段,Sec-Websocket-Key与Sec-Websocket-Accept。
S e c W e b s o c k e t A c c e