HTML5的Comet方案EventSource
之前的一些文章虽然介绍过了Comet的几个基本方案,不过它们都是通过XHR对象来实现的。其实,现代浏览器已经对Comet进行了封装,HTML5中提供了EventSource这个API来直接处理Comet。只是IE目前还没有兼容它,对于IE依然需要使用传统的XHR方式。无论何种方式的Comet,都需要关联到服务器程序上。所以,这回的例子咱也先来看看服务器程序。
//设置EventSource需求的MIME
header("content-type: text/event-stream");
//输出当前时间
echo 'data:现在是北京时间:'.date('H:i:s')."\r\n\r\n";
//发送数据到客户的(如果有开启ob需要先调用ob_flush)
flush();
接着咱来看客户端的接收部分。比起XHR方式,使用EventSource要简单的多的多的多!下面是代码,就三行而已
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body onload="init()">
<button onClick="quit()">退出</button>
<div id="msg" style="border:1px dashed #c3c3c3;"></div>
</body>
</html>
<script type="text/javascript">
//声明一个EventSource:source;
var source;
//初始化调用方法
function init(){
var url="test.php";
source=new EventSource(url);
try{
source.onopen=function(event){
p("连接已经建立,状态号:"+this.readyState);
}
source.onmessage=function(event){
p('客户端收到服务器推送的数据是:'+event.data);
var res = eval('(' + event.data + ')');;
p('客户端收到服务器推送的数据是:'+res.time);
}
source.onerro=function(event){
p("出错,信息状态号是:"+this.readyState);
}
}catch(err){
alert('出错啦,错误信息:'+err.message);
}
}
//退出方法,关闭EventSource
function quit(){
p("已经成功退出啦!");
source.close();
source=null;
}
//信息输出方法
function p(msg){
document.getElementById("msg").innerHTML+="<br/>"+msg;
}
</script>
直接new它,把服务器程序作为构造参数来使用即可。然后在返回的对象上绑定onmessage就能收到消息了。
以上这些就是EventSource最基本的用法。当然它还有其它的属性和方法,这个可以在MDN上找到,我就不演示了。我给出的例子是数据流方式的,实际上EventSource也有轮询的功能,当服务器端返回200代码并主动断开连接时,客户端会自动重新发起请求。所以即使前面的PHP程序中不调用“set_time_limit(0)”也不会有太大问题。不过我比较推荐数据流方式的用法,至少它的性能开销比轮询方式好一些。