为什么需要服务器推送?
最大的优点实时
适用场景实时股票价格商品价格实时新闻Twitter/weibo timeline基于浏览器的聊天系统
Web交互的发展历程?
F手动刷新 > AJAX轮询(Polling) > Comet实时更新 > HTML实时通信
随着AJAX的流行当前大部分网站都采取轮询的方式进行更新但是这种方式的效率是十分低下的一方面服务器端不是总有数据更新所以每次请求不一定都有更新另一方面当发起请求的客户端数量增加服务器端的接受的请求数量会大量上升无形中就增加了服务器的压力
另外轮询方式的实时性也是不够的比如基于Web的聊天功能对实时性要求就很高于是comet出现了Comet是基于HTTP长连接的服务器推送技术主要有流(streaming)方式和长轮询(longpolling)方式Comet工作原理用户发起请求后就挂起等待服务器返回数据在此期间不会断开连接流方式和长轮询方式的区别是对于流方式客户端发起连接就不会断开连接而是由服务器端进行控制当服务器端有更新时刷新数据客户端进行更新而对于长轮询当服务器端有更新返回客户端先断开连接进行处理然后重新发起连接
Comet虽然是一个进步但是其仍然是单向通信不能适应Web应用的飞速发展于是各种新技术不断涌现其中WebSocket在Google的力推之下已经成为业界标准并不断完善中
下面简单介绍一下Comet的实现方式
Comet的实现方式
基于AJAX和基于IFrame的流(streaming)方式
从上图可以看出每次数据传送不会关闭连接连接只会在通信出现错误时或是连接重建时关闭(一些防火墙常被设置为丢弃过长的连接 服务器端可以设置一个超时时间 超时后通知客户端重新建立连接并关闭原来的连接)
基于AJAX的长轮询(longpolling )方式
从上图可以看出客户端发出请求后挂起服务端在接到请求也挂起等待有更新时返回数据并断掉连接然后客户端再发起新的连接
HTML实时通信
ServerSent Event只支持单向的从服务器到客户端的通道
ServerSent Events实际上将Comet技术进行了标准化ServerSent Events规范定义了API来打开一个HTTP连接通过该连接能够获取从服务器推送的通知
ServerSent Events包含新的HTML元素EventSource和新的MIME类型 text/eventstream这个MIME类型定义了事件框架格式
EventSource代表的是接收事件的客户端的终点客户端通过创建EventSource对象来打开一个event stream创建EventSource对象时该对象接收一个事件来源的URL作为其构造函数的参数当每次收到新的事件数据时onmessage事件处理器会被调用
ServerSent Event是基于HTTP streaming的如上所述response会一直打开当服务器端有事件发生的时候事件会被写入response中
WebSocket基于TCP之上定义了帧协议支持双向的通信
WebSocket 是HTML一种新的协议它是实现了浏览器与服务器的双向通讯
在 WebSocket API 中浏览器和服务器只需要要做一个握手的动作然后浏览器和服务器之间就形成了一条快速通道两者之间就直接可以数据互相传送
现在很多网站为了实现即时通讯所用的技术都是轮询轮询是在特定的的时间间隔(如每秒)由浏览器对服务器发出HTTP request然后由服务器返回最新的数据给客户端的浏览器这种传统的模式带来很明显的缺点即浏览器需要不断的向服务器发出请求然而HTTP request 的header是非常长的里面包含的数据可能只是一个很小的值这样会占用很多的带宽和服务器资源
而比较新的技术去做轮询的效果是Comet使用了AJAX但这种技术虽然可达到双向通信但依然需要发出请求而且在Comet中普遍采用了长链接这也会大量消耗服务器带宽和资源
面对这种状况HTML定义了WebSocket协议能更好的节省服务器资源和带宽并达到实时通讯