Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

HTML5的Comet方案EventSource

  之前的一些文章虽然介绍过了Comet的几个基本方案,不过它们都是通过XHR对象来实现的。其实,现代浏览器已经对Comet进行了封装,HTML5中提供了EventSource这个API来直接处理Comet。只是IE目前还没有兼容它,对于IE依然需要使用传统的XHR方式。
  无论何种方式的Comet,都需要关联到服务器程序上。所以,这回的例子咱也先来看看服务器程序。 //关闭脚本超时
set_time_limit(0);
//设置EventSource需求的MIME
header("content-type: text/event-stream");
//死循环来做长连接的工作
while(1){
  //输出当前时间
  echo 'data:现在是北京时间:'.date('H:i:s')."\r\n\r\n";
  //发送数据到客户的(如果有开启ob需要先调用ob_flush)
  flush();
  //等待一秒
  sleep(1);
};
  这个程序会每秒输出一个当前时间,直到与客户端断开连接。这里设置了个比较特殊的MIME“text/event-stream”,它是EventSource必要的。如果不设置这个MINE用EventSource直接请求的话会抛出MIME不正确的异常。后面的循环体中,输出数据的格式也是有要求的,它不像我们之前使用XHR方式实现的数据流式Web通信那样随便。既然是内部封,我们就应该按照它本身的套路来。输出数据需要使用“data:”前缀,然后才是发送的文本。而且需要用双换行来表示一个数据的结束,所以我的程序中给数据后面加上了“\r\n\r\n”(其实“\n\n”也可以)。这样,每次循环就都能发送一个完整的数据了。
  接着咱来看客户端的接收部分。比起XHR方式,使用EventSource要简单的多的多的多!下面是代码,就三行而已 //创建一个EventSource对象,并绑定上message事件(接收到消息时触发)
new EventSource("test.php").onmessage=function(e){
  //把数据输出到控制台
  console.log(e.data);
};
  直接new它,把服务器程序作为构造参数来使用即可。然后在返回的对象上绑定onmessage就能收到消息了。

  以上这些就是EventSource最基本的用法。当然它还有其它的属性和方法,这个可以在MDN上找到,我就不演示了。我给出的例子是数据流方式的,实际上EventSource也有轮询的功能,当服务器端返回200代码并主动断开连接时,客户端会自动重新发起请求。所以即使前面的PHP程序中不调用“set_time_limit(0)”也不会有太大问题。不过我比较推荐数据流方式的用法,至少它的性能开销比轮询方式好一些。
  参考:
    MDN EventSource
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^