Websocket
WebSocket 是什么
WebSocket 是一种网络通信协议。那么就有一个问题了:已经有了 HTTP 协议,为什么还需要 WebSocket? 因为 HTTP 协议有一个缺陷:通信只能由客户端发起,做不到服务器主动向客户端推送信息。 HTTP 协议的这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用“轮询”:每隔一段时候,就发出一个询问,了解服务器有没有新的信息。轮询的效率低,非常浪费资源。因此,大佬们一直在思考,有没有更好的方法。WebSocket 就是这样出现的。
有基于 HTTP 实现的 EventSource 可以做到服务器向客服端主动发起消息
WebSocket 特点
WebSocket 协议在 2008 年诞生,2011 年成为国际标准。所有浏览器都已经支持了。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。 WebSocket 允许服务器端与客户端进行全双工的通信。
其他的一些特点:
- 建立在 TCP 协议之上,服务器端的实现比较容易。
- 与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
- 数据格式比较轻量,性能开销小,通信高效。
- 可以发送文本,也可以发送二进制数据。
- 没有同源限制,客户端可以与任意服务器通信,完全可以取代 Ajax。
- 协议标识符是 ws(如果加密,则为 wss,对应 HTTPS 协议),服务器网址就是 URL。
WebSocket 握手
WebSocket 也要有一个握手过程,然后才能正式收发数据。
客户端发送数据格式如下:
json
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
- Connection:必须设置 Upgrade,表示客户端希望连接升级
- Upgrade:必须设置 Websocket,表示希望升级到 Websocket 协议
- Sec-WebSocket-Key:客户端发送的一个 base64 编码的密文,用于简单的认证秘钥。要求服务端必须返回一个对应加密的“Sec-WebSocket-Accept 应答,否则客户端会抛出错误,并关闭连接
- Sec-WebSocket-Version :表示支持的 Websocket 版本
服务端返回的数据格式:
json
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Sec-WebSocket-Protocol: chat
- HTTP/1.1 101 Switching Protocols:表示服务端接受 WebSocket 协议的客户端连接
- Sec-WebSocket-Accep:验证客户端请求报文,同样也是为了防止误连接。具体做法是把请求头里“Sec-WebSocket-Key”的值,加上一个专用的 UUID,再计算摘要
总结
WebSocket 是一种基于 TCP 的网络通信协议。 优点如下:
- 较少的控制开销:数据包头部协议较小,不同于 http 每次请求需要携带完整的头部
- 更强的实时性:相对于 HTTP 请求需要等待客户端发起请求服务端才能响应,延迟明显更少
- 保持创连接状态:创建通信后,可省略状态信息,不同于 HTTP 每次请求需要携带身份验证
- 更好的二进制支持:定义了二进制帧,更好处理二进制内容
- 支持扩展:用户可以扩展 websocket 协议、实现部分自定义的子协议
- 更好的压缩效果:Websocket 在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率