zoukankan      html  css  js  c++  java
  • Web通信之:长轮询(long-polling)(转)

    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部分我就不注释了 //检测浏览器
    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通信的另一种方法吧。

  • 相关阅读:
    Android事件机制之一:事件传递和消费
    Android单个控件占父控件宽度一半且水平居中
    Android IllegalArgumentException: Cannot draw recycled bitmaps解决方法
    Android视图篇之一:Android常见基本布局
    Android Nine-patch(.9.png)小结
    adb server is out of date. killing... ADB server didn't ACK解决方法
    Docker 下自定义安装 Tomcat
    Docker 删除 images
    SecureCRT 取消右击粘贴功能
    如何将不同业务模块产生的日志 分多文件记录
  • 原文地址:https://www.cnblogs.com/tonykan/p/3468548.html
Copyright © 2011-2022 走看看