服务器端给客户端推送消息的方式:
HTTP 定时轮询
- 如扫码登录,一般间隔 1、2 秒请求询问,确定是否有扫码。
- 大量的http请求,消耗带宽,增加下游服务器的负担。
- 间隔短用户体验好,间隔较长省带宽。
HTTP 长轮询
- 将请求超时设的很大,如 30 秒,期间服务器收到了扫码请求,立马返回给客户端。如果超时,立马发起下一次请求。
- 减少了请求数,且大多 30 秒内扫码完成,因此响应快、体验更好。
- 如果超时,就需要用户刷新二维码,促进用户扫码速度
- 我们常用的消息队列 RocketMQ 中,消费者去取数据时,也用到了这种方式。
- 这两种方式只适用于简单的推送一些数据量比较少的数据,但是如果是网页游戏,需要大量推送就不合适了
HTTP虽然给予全双工的TCP,但是HTTP/1.1同一时间只有一方主动发送数据,且服务器不能主动推送
- 因为设计之初是用来浏览网页文本,只需要客户端请求服务器响应即可
WebSocket
- 网页连接之初还是使用 HTTP,如果想建立 WebSocket,会在 header 添加升级标识。
- 如果服务器支持,进行升级,之后就不再使用 HTTP 了。是全双工双向通信。
- WebSocket 使用数据头+payload 的方式解决粘包
- 一般适用于网页游戏、聊天室等。
- WebSocket 使用 ws:// 或 wss://(使用 SSL/TLS 加密后的协议,类似于 HTTP 和 HTTPS 的关系) 作为协议前缀,HTTP 使用 http:// 或 https:// 作为协议前缀。
- WebSocket 通信数据格式比较轻量,用于协议控制的数据包头部相对较小,网络开销小,而 HTTP 通信每次都要携带完整的头部,网络开销较大(HTTP/2.0 使用二进制帧进行数据传输,还支持头部压缩,减少了网络开销)。
- 客户端或服务器可以主动发送一个关闭帧,表示要断开连接。另一方收到后,也会回复一个关闭帧,然后双方关闭 TCP 连接。
另外,建立 WebSocket 连接之后,通过心跳机制来保持 WebSocket 连接的稳定性和活跃性。
SSE (推荐)
- 服务器发送事件(Server-Sent Events),如 ChatGPT
- 基于 HTTP 协议,在服务器和客户端之间打开一个单向通道,服务端响应是数据流,可以理解为一次长下载。
- SSE 单向通信,只能由服务端向客户端单向通信
- SSE 实现简单开发成本低,无需引入其他组件;WebSocket 传输数据需做二次解析,开发门槛高一些。
- SSE 默认支持断线重连;WebSocket 则需要自己实现。
- SSE 只能传送文本消息,二进制数据需要经过编码后传送;WebSocket 默认支持传送二进制数据。
注意: SSE 不支持 IE 浏览器,对其他主流浏览器兼容性做的还不错。

