简介
轮询、长连接和 WebSocket 都是实现 Web 即时通信的机制。根据基于的协议可以分为两类:基于 HTTP 协议实现和基于 WebSocket 协议实现。
这里主要介绍基于 HTTP 协议的三种方式:短轮询、长轮询和长连接。
短轮询
定义
短轮询就是普通的、常规的轮询:浏览器每隔一段固定的时间就像服务器发送 HTTP 请求,服务器在收到请求后,不管是否有数据需要发送更新,都直接进行响应。
本质上还是浏览器发送请求,服务器接收请求的过程
实现
1 | var xhr = new XMLHttpRequest(); |
特点
- 实现简单;
- 因为需要不断的建立新的 HTTP 连接,非常浪费服务器和客户端的资源;
- 响应的结果没有顺序并且包含一定的延时;
长轮询:comet
流程
- 客户端发送 Ajax 请求到服务器,服务器在有消息之前将该请求挂起。
- 当服务端数据更新或者有消息后,服务器将作出响应。如果一直没有数据更新,则到达一定的时间限制也会做出响应。
- 客户端处理服务器的响应后,立即发出一个新的请求。
实现
1 | function ajax(){ |
特点
优点
- 和短轮询相比数据未更新时不会频繁的请求,耗费的资源少。
缺点
- 服务器挂起连接会消耗服务器的资源;
- 响应数据没有顺序;
- 在同一时刻,客户端对相同服务器的 HTTP 连接数量有最大限制。最好同一个用户只存在一个长轮询。
长连接:SSE
定义
长连接是 HTTP/1.1 中出现的。它本质上和轮询机制不同,允许多个 HTTP 请求共用一个 TCP 连接。服务器只要数据有更新就可以马上发送到客户端。
SSE:Server-Sent Events
可以减少频繁建立 TCP 连接所带来的资源浪费和时间损耗。
实现
1 |
|
1 | //produces 必须为"text/event-stream;charset=UTF-8" |
特点
优点
- 多个 HTTP 请求共用一个 TCP 连接,不需要建立或保持大量的请求。
缺点
- 服务器维护一个长连接会增加开销。
- 浏览器对同一个域有并发数量限制,长连接会持续性的占用浏览器和服务器的一个连接,从而资源无法释放。
例:Chrome 浏览器对于并发数量的限制为 6
对比 WebSocket 协议
- SSE 使用 HTTP 协议,现有的服务器软件都支持。WebSocket 是一个独立协议。
- SSE 通常只用来传送文本,二进制数据需要编码后传送。WebSocket 默认支持传送二进制数据。
- SSE 属于轻量级,使用简单。WebSocket 协议相对复杂。
- SSE 默认支持断线重连。WebSocket 需要自己实现。
- SSE 支持自定义发送的消息类型。
- SSE 是 单通道,WebSocket 是双通道。
单通道:使用 SSE 时,服务端向客户端发消息且占用一个连接。如果客户端要向服务端通信,需额外打开一个连接。