Skip to content

服务器端给客户端推送消息的方式:

  • 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 浏览器,对其他主流浏览器兼容性做的还不错。

SSE 兼容性

正在精进