前言
最近项目中要实现一个进度条的功能,要求百分比显示服务端同步数据的进度,并实时展示服务器处理进度(实时展示进度日志)。
受领导之托,我先调研对比了以下几种前后端通信方案,应该比较全了,后续做完这个功能我会把具体实现demo分享更新上来
传统轮询(Traditional Polling) | 长轮询(Long Polling) | SSE(Server-Sent Events) | WebSocket | socket.io | |
---|---|---|---|---|---|
浏览器支持 | 几乎所有现代浏览器 | 几乎所有现代浏览器 | Firefox 6+ Chrome 6+ Safari 5+ Opera 10.1+;不支持 IE 浏览器 | IE 10+ Edge Firefox 4+ Chrome 4+ Safari 5+ Opera 11.5+ | 几乎所有现代浏览器 |
实现方式 | setInterval或者setTimeout | setInterval或者setTimeout,设置一个较大的timeout值 | HTML5 new EventSource() | HTML5 new WebSocket() | Socket.IO库,封装了 WebSocket 和其他实时通信协议,并提供了一组易于使用的 API。它既可以在客户端上使用,也可以在服务器端上使用,它还提供了许多高级功能,例如自动重连、心跳机制和房间等概念。自带多种传输方式,如 WebSocket、HTTP 长轮询、JSONP 等,可以根据浏览器或设备的不同选择最佳传输方式。 |
协议和通信方式 | 普通http | 普通http | http,服务端->客户端单向通信 | TCP,双向通信 | * |
服务器负载 | 较少的CPU资源,较多的内存资源和带宽资源 | 与传统轮询相似,但是占用带宽较少 | 与长轮询相似,除非每次发送请求后服务器不需要断开连接 | 无需循环等待(长轮询),CPU和内存资源不以客户端数量衡量,而是以客户端事件数衡量。四种方式里性能最佳。 | * |
客户端负载 | 占用较多的内存资源与请求数。 | 与传统轮询相似。 | 浏览器中原生实现,占用资源很小。 | 同Server-Sent Event。 | * |
延迟 | 非实时,延迟取决于请求间隔。 | 同传统轮询。 | 非实时,默认3秒延迟,延迟可自定义。 | 实时。 | * |
实现复杂度 | 非常简单。 | 需要服务器配合,客户端实现非常简单。 | websocket轻量级的替代品,需要服务器配合,而客户端实现甚至比前两种更简单。 | 需要Socket程序实现和额外端口,客户端实现简单。 | 使用 Socket.IO 的应用程序需要使用 Socket.IO 作为通信层,不能在应用程序中集成原生 WebSocket 或 EventSource。对比 EventSource 和 WebSocket,Socket.IO 相对来说更加庞大,需要引入相应的客户端库和服务器端插件,如果应用程序只需要简单的实时通信,使用 EventSource 或 WebSocket 可能更加适合 |
数据类型 | http contentType | http contentType | 无法发送二进制数据。 服务器响应格式: 服务器发送由 \n\n 分隔的消息。 一条消息可能有以下字段: 1. data: —— 消息体(body),一系列多个 data 被解释为单个消息,各个部分之间由 \n 分隔。 2. id: —— 更新 lastEventId,重连时以 Last-Event-ID 发送此 id。 3. retry: —— 建议重连的延迟,以 ms 为单位。无法通过 JavaScript 进行设置。 4. event: —— 事件名,必须在 data: 之前。 一条消息可以按任何顺序包含一个或多个字段,但是 id: 通常排在最后。 | 可以发送二进制数据,支持大文件传输 | * |
安全性 | 同http请求 | 同http请求 | 只监听服务器推送的消息,安全性较高 | 需要注意防止 CSRF 和 XSS 攻击,避免恶意用户利用 WebSocket 劫持会话或注入脚本等。 | * |