被问到这个问题,其实也就是说服务器不断地给浏览器发送消息的逻辑。
Javascript高级程序设计里面正好有讲到这个问题,一个解决方案是Comet,包括长轮询和流,另外一个实现方案是web socket
Comet
属于一种高级的Javascript技术,实现技术包括长轮询和流,适合处理体育比赛的分数和股票报价
长轮询
长轮询的实现原理,其实就是ajax的服务器延迟发送版本,图21-1是短轮询,服务器收到请求就立马回复信息,长轮询把短轮询颠倒了一下。页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到有数据可发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的新请求。这一过程在页面打开期间一直持续不断。图21-2 展示了长轮询的时间线。
流
长轮询每次发送请求都会打开一次http,流在所有的时间里面只打开一次http请求,然后因为不断地发送数据,所以只要readystatechange 事件发生,而且readyState 值为3,就对responseText 进行分割以取得最新数据
SSE
之前的算原理,SSE是浏览器实现的API
var source = new EventSource("myevents.php");
注意,传入的URL 必须与创建对象的页面同源(相同的URL 模式、域及端口)。EventSource 的实例有一个readyState 属性,值为0 表示正连接到服务器,值为1 表示打开了连接,值为2 表示关闭了连接。
另外,还有以下三个事件。
open:在建立连接时触发。
message:在从服务器接收到新事件时触发。
error:在无法建立连接时触发。
就一般的用法而言,onmessage 事件处理程序也没有什么特别的。
source.onmessage = function(event){
var data = event.data;
//处理数据
};
服务器发回的数据以字符串形式保存在event.data 中。
默认情况下,EventSource 对象会保持与服务器的活动连接。如果连接断开,还会重新连接。这就意味着SSE 适合长轮询和HTTP 流。如果想强制立即断开连接并且不再重新连接,可以调用close()方法。
source.close();
comet和web socket的比较
- comet是http协议,web socket协议的开销比起http小,适合移动端
- web socket需要专门的服务器支持,另外浏览器的支持程序也不高
- 场景的选择的话,comet适合服务器单向,而web socket适合双向