Web 技术研究所

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

Web通信之:长轮询(long-polling)

  “轮询”是个耐人寻味的词,第一次看到它的时候我就直接理解为“轮流查询”了。但是看到了英文才知道这个是网络通信专业的术语。轮询,其实就是一群人在排队买东西。polling这个词也生动的形容了这个的状态。就像这样

  轮询如果是排队买东西,那么长轮询就是排队上厕所。买东西的话,丢下钱就可以拿东西走了,但是上厕所就不一样,有些人说不定便秘半个小时都出不来。如果只用轮询去做Web通信,那服务器就鸭梨山大了,它需要一直做的接受和断开HTTP请求的操作。就像卖热销产品的店员就没有公共厕所管理员那么轻松。
  服务器就是厕所,需要上厕所的就是客户端的XHR对象。这就是长轮询的实现原理了。现在我做了一个例子,这个例子是当服务器上的某个文件被修改的时候就会把那个文件的内容输出到客户端,如果没有修改就一直保持“便秘”状态。我们先看服务器端的代码 <?
//设置当前脚本为无超时状态
set_time_limit(0);
//操作的文件名
$DATAFILE='dat.txt';
//保存当前时间
$time=time();
//用死循环持续检测文件
while(1){
  //判断文件存在
  file_exists($DATAFILE) and
  //判断文件修改
  filemtime($DATAFILE)>$time and
  //输出文件内容并断开HTTP
  die(file_get_contents($DATAFILE));
  //清空文件状态缓存
  clearstatcache();
  //等待1秒
  sleep(1);
};
?>
  接着是客户端的代码,AJAX部分我就不注释了 function polling(url){
  //创建IE兼容的XHR对象
  var xhr=window.XMLHttpRequest
    ?new XMLHttpRequest
    :new ActiveXObject("Microsoft.XMLHTTP");
  xhr.onreadystatechange=function(){
    if(xhr.readyState!=4)return;
    //把接收到的文字输出
    var div=document.createElement("div");
    div.appendChild(
      document.createTextNode(xhr.responseText)
    );
    document.body.appendChild(div);
    polling(url); //间接递归
  };
  xhr.open("GET",url,true);
  xhr.send();
};
polling("test.php");
  这样,当我们每次修改dat.txt并保存的时候,新的内容就会被输出到客户端。收到信息后客户端会再让一个XHR对象连接服务器等待dat.txt的下一次修改。

  以上就是长轮询的工作方式了。上面的例子只是说明了长轮询的工作原理,监视一个文件的改变只是一种操作方式而已。在你的程序中,可以监视数据库的变化或者做其他操作来判断是否要把数据输出到客户端。而且,数据并不局限于text/plain,你可以发送HTML、XML、JSON等所有你想要的格式让客户端程序自己去解析。
  比起轮询,长轮询可以节省很多HTTP连接和断开操作带来的开销。但是依然会消耗很多服务器资源,明天我们来说说Web通信的另一种方法吧。
网名:
54.92.174.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^