web实时通信方案
# web实时通信相关概念
# 通讯传输模式
单工:只支持数据在一个方向上传输;例如:BP 机
半双工:允许数据在两个方向上传输,但是某一时刻只允许数据在一个方向上传输;例如:对讲机, 电报机
全双工:同时在两个方向上传输,是两个单工通信的结合,要求发送设备和接收设备同时具有独立的接收和发送能力。 例如:手机
# 实时通信方案
# 轮询(polling)
轮询是客户端和服务器之间会一直进行连接,每隔一段时间就询问一次
优点:实现简单,无需做过多的更改
缺点:
轮询的间隔过长,会导致用户不能及时接收到更新的数据;
轮询的间隔过短,会导致查询请求过多,增加服务器端的负担
# 长轮询(long-polling)
长轮询是对轮询的改进版,客户端发送 HTTP 给服务器之后,看有没有新消息,如果没有新消息,就一直等待。当有新消息的时候,才会返回给客户端。在某种程度上减小了网络带宽和 CPU 利用率等问题。由于 http 数据包的头部数据量往往很大(通常有 400 多个字节),但是真正被服务器需要的数据却很少(有时只有 10 个字节左右),这样的数据包在网络上周期性的传输,难免 对网络带宽是一种浪费 。
优点:比 Polling 做了优化,有较好的时效性 缺点:保持连接会消耗资源; 服务器没有返回有效数据,程序超时。
# EventSource
事件流 EventSource(SSE - Server-Sent Events 单向通信)服务端派发事件
EventSource 基于 http 协议只是简单的单项通信,实现了服务端推的过程客户端无法通过 EventSource 向服务端发送数据。
虽然不能实现双向通信但是在功能设计上他也有一些优点比如可以自动重连接,event-IDs,以及发送随机事件的能力
适用场景:
因为受单项通信的限制 EventSource 非常适应于后端数据更新频繁且对实时性要求较高而又不需要客户端向服务端通信的场景下 比如来实现像股票报价、新闻推送、实时天气这些只需要服务器发送消息给客户端场景中。EventSource 的使用更加便捷这也是他的优点。
优点:
基于现有 http 协议,实现简单
断开后自动重联,并可设置重联超时
派发任意事件
跨域并有相应的安全过滤
缺点:
只能单向通信,服务器端向客户端推送事件
事件流协议只能传输 UTF-8 数据,不支持二进制流。
兼容性不高,IE 和 Edge 下目前所有不支持 EventSource
服务器端需要保持 HTTP 连接,消耗一定的资源
注意点:
EventSource 是一种服务端推送技术。
一般来说,网页都是通过发送请求从服务端获取数据,而服务端推送技术 使服务器随时可以向客户端发送数据。
EventSource 基于 http 长链接
(1)客户端需要创建一个 EventSource 对象,服务端 URI 为参数
(2)服务端返回的响应报文的 Content-Type 须为 text/event-stre
# WebSocket
WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
HTML5 定义的 WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯;解决了轮询以及其他长连接的很多缺点。
# Socket.io
Socket.io是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用(不支持WebSocket的情况会降级到AJAX轮询),非常方便和人性化,兼容性非常好,支持的浏览器最低达IE5.5。屏蔽了细节差异和兼容性问题,实现了跨浏览器/跨设备进行双向数据通信。
# WebSocket & EventSource 的区别
EventSource和WebSocket一样都是HTML5中的新技术,不过两者在定位上有很大的差别。
WebSocket基于TCP协议,EventSource基于http协议。
EventSource是单向通信,而websocket是双向通信。
EventSource只能发送文本,而websocket支持发送二进制数据。
在实现上EventSource比websocket更简单。
EventSource有自动重连接(不借助第三方)以及发送随机事件的能力。
websocket的资源占用过大EventSource更轻量。
websocket可以跨域,EventSource基于http跨域需要服务端设置请求头。