服务端推送技术
Last updated: Jun 14, 2020
在现实世界中,我们可能会服务端在发生数据变化后能够以较低的延迟通知到客户端,这是我们就需要一个服务端推送方案。本文将介绍一些服务器端推送方案的思路,并逐一分析其优缺点。这些方案包含短轮询、长轮询、WebSocket、SSE和注册回调。
1. 短轮询
客户端设置一个定时任务,每隔一段时间都向服务端发送HTTP请求。
严格来说,此方案并非推送方案,本质上还是有客户端向服务端拉取数据。
1.1. 优点
- 实现简单直接,客户端和服务端在实现上都不容易出错。
- 兼容性最好,基本没有什么条件限制
1.2. 缺点
- 会产生大量无意义的数据传输
- 实时性差,定时任务需要存在一定间隔,HTTP每次请求响应也损耗一定时间
2. 长轮询
- 客户端向服务端发送HTTP请求,请求中携带客户端当前数据版本号。
- 服务端在收到请求后不会直接响应,而是阻塞此处请求一段时间。
- 在阻塞期间如果发现该请求中携带数据版本号已经不是最新,则立即将新数据返回给客户端。
- 如果超过一定时间数据未变化,则通知客户端数据未发生变化。
- 无论客户端有无收到新数据,马上返回步骤1形成循环监听。
尽管此方案依然是由客户端发起请求,但是在阻塞阶段的数据是有服务端推送给客户端。
2.1. 优点
- 实现相对简单
- 兼容性较好,对网络条件基本没有什么要求
- 解决了短轮询的频繁请求问题
2.2. 缺点
- 要与客户端对超时时间方面形成约定,否则客户端超时断开连接会导致永远接收不到信息
- 每个客户端都与服务端会保持一个连接,依然会造成一定的资源占用
3. WebSocket
WebSocket协议是建立在TCP之上的,借用HTTP协议的101 switchprotocol(服务器根据客户端的指定,将协议转换成为 Upgrade首部所列的协议)来达到协议转换的,从HTTP协议切换成WebSocket通信协议。
WebSocket是纯事件驱动的,一旦 WebSocket 连接建立后,通过监听事件可以处理到来的数据和改变的连接状态。数据都以帧序列的形式传输。服务端发送数据后,消息和事件会异步到达。
3.1. 优点
- 全双工,功能强大
- 资源消耗少
3.2. 缺点
- 实现较为复杂,需要客户端和服务端建立并维护TCP套接字通信
- 对中间网络链路有一定要求,例如中间的代理转发节点可能需要特殊配置以支持WebSockt
4. SSE(Server-sent Events)
SSE与长轮询机制类似,区别是每个连接不只发送一个消息。客户端发送一个请求,服务端保持这个连接直到有新消息发送回客户端,仍然保持着连接,这样连接就可以消息的再次发送,由服务器单向发送给客户端。
SSE本质是发送的不是一次性的数据包,而是一个数据流。服务端连续不断的发送,客户端不会关闭连接,如果连接断开,客户端会尝试重新连接。如果连接被关闭,客户端可以被告知使用204无内容响应代码停止重新连接。
与WebSocket的全双工不同,SSE是半双工的协议,其只能由服务端向客户端单向发送数据。
4.1. 优点
- 实现上比WebSocket简单
- 资源消耗较少
4.2. 缺点
- 使用上没有没有轮询方便,扩展性也略逊轮询方案
- 对网络链路有一定要求,需要代理服务器支持,有些代理服务器会在响应HTTP结束后才转发给客户端
5. 注册回调
客户端实现一个接口用于接收数据,在首次向服务端请求数据的同时,将此接口注册给服务端。服务端在发现数据变更时,会回调当时客户端注册的接口,以推送数据给客户端,或是通知客户端数据发送了变更。
5.1. 优点
- 根本是解决了无效数据交互的问题
5.2. 缺点
- 实现复杂,要求客户端做的工作更多
- 对网络环境要求高,需要服务端可以访问到客户端地址