• 长轮询Long Polling的通俗解释

    类比排队上厕所
    服务器君一共花费 5.444 ms 进行了 3 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    “轮询”是个耐人寻味的词,第一次看到它的时候我就直接理解为“轮流查询”了。但是看到了英文才知道这个是网络通信专业的术语。轮询,其实就是一群人在排队买东西。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部分我就不注释了:

    //检测浏览器
    var isIE=navigator.userAgent.match(/MSIE (\d)/i);
    isIE=isIE?isIE[1]:undefined;
    (function(){
      var xhr,f;
      //保存当前函数
      f=arguments.callee;
      xhr=isIE < 9
        ?new ActiveXObject("Microsoft.XMLHTTP")
        :new XMLHttpRequest;
      xhr.onreadystatechange=function(){
        if(xhr.readyState==4){
          //把接收到的文字输出
          var div=document.createElement("div");
          div.appendChild(
            document.createTextNode(xhr.responseText)
          );
          document.body.appendChild(div);
          f();//间接递归
        };
      };
      xhr.open("GET","test.php",true);
      xhr.send();
    })();
    

    这样,当我们每次修改dat.txt并保存的时候,新的内容就会被输出到客户端。收到信息后客户端会再让一个XHR对象连接服务器等待dat.txt的下一次修改。

    以上就是长轮询的工作方式了。上面的例子只是说明了长轮询的工作原理,监视一个文件的改变只是一种操作方式而已。在你的程序中,可以监视数据库的变化或者做其他操作来判断是否要把数据输出到客户端。而且,数据并不局限于text/plain,你可以发送HTML、XML、JSON等所有你想要的格式让客户端程序自己去解析。

    比起轮询,长轮询可以节省很多HTTP连接和断开操作带来的开销。但是依然会消耗很多服务器资源,我们后面再说说Web通信的另一种方法吧。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [软件工程与项目管理] 浏览器与CSS渲染技巧 2 个条目
  2. [软件工程与项目管理] 了解一点WebKit 9 个条目
  3. [移动开发] 从代码角度去认识 Handler 4 个条目
  4. [PHP程序设计] PHP里的布尔类型 3 个条目
  5. [智力开发与知识管理] 信息的类型与结构 9 个条目
  6. [移动开发] Layout_weight属性解析 5 个条目
  7. [PHP程序设计] 声明式编程范式 12 个条目
  8. [Python程序设计] Django 入门知识浅介 10 个条目
  9. [Linux操作系统] CentOS上使用EPEL Repository 2 个条目
  10. [Python程序设计] Python语言概述 6 个条目
  11. [移动开发] Android开发基础知识 4 个条目
  12. [Python程序设计] urls.py设置技巧 8 个条目
窗口 -- [资讯]