• 使用Ajax建立的Server Push和Iframe建立的Comet


    1、Ajax建立的Server Push

    只能由后台向前台推送数据,如果前台想发送数据给后台则需要单独再发一个请求。

    这里使用的例子就是一个在线CD销售页面,前台发起ajax请求,后台随机取一个数,从现在库中减去获得的随机数,然后返回给前台;

    前台如果想改变库存的数据,在文字输入框输入相应的数量,然后提交给后台。

    界面大致是这个样子

    image

    图中的“27”就是剩余的CD数量,上文提及的“库存”实际是使用一个txt文本进行保存的。

    因为代码是从网上一篇文章(可点击查看详情)中下载过来的,他使用了prototype中的ajax,这里就没有作修改。需要下载源代码的,请点击这里>>

    需要说明的,它的主页中form的默认提交行为没有被阻止掉,将会导致页面被刷新。可以使用onsubmit=”return false;”进行阻止,AjaxLongPolling.js的初始化函数中对form的submit再进行监听就可以了。

    目录结构大致是这样子:

    image

    页面载入完成后,向后台发送ajax请求,当ajax成功返回后将重复执行上一次操作(直到返回的数量为0,则中止上述循环)

    function connectToServer() {
    new Ajax.Updater({
    success : 'CD Count',
    failure : 'errors'
    }, 'LongPolling.php', {
    method : 'get',
    onSuccess : function(transport) {
    if (parseInt(transport.responseText)) {
    connectToServer();
    }
    }
    });
    }

    想要修改后台的“库存”数量,则需要另外一个ajax

    function purchaseCD() {
    new Ajax.Updater({
    success : 'CD Count',
    failure : 'errors'
    }, 'LongPolling.php', {
    method : 'get',
    parameters : {
    num : $('txtQty').getValue()
    }
    });
    }

    虽然是同一个提交地址LongPolling.php,但在LongPolling.php中是针对参数进行了处理的

    <?php

    $cd_stock = ("CdCount.txt");

    function updateStock($num) {
    global $cd_stock;
    $count = file($cd_stock);
    $count = (int)$count[0];
    $count = $count - $num;
    if ($count < 0) $count = 0;
    $fp = fopen($cd_stock , "w");
    fputs($fp , "$count");
    fclose($fp);

    echo $count;
    }

    function getCdCount()
    {
    srand();
    $newOrder = rand(1, 3);
    $sleeptime = rand(2, 10);
    sleep(1);

    updateStock($newOrder);
    }

    $num = $_GET['num'];
    if ($num == "") {
    getCdCount();
    } else {
    updateStock((int)$num);
    }
    ?>

     
    2、使用Iframe建立的Comet
     
    这里针对IE和其它浏览器做了不同的处理,因为IE中的htmlfile添加的iframe,在浏览器当前窗口的底部将看不到加载进度(看上去比较平静),而其它浏览器则会出现一个loading的状态。
    这个示例就两个文件:html页面、php页面,实现的效果就是取当前服务器的时间,然后在前台页面显示。
     
    运行的效果大致如下图所示(IE、Chrome):
    image
    image
     
    HTML页面的代码:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>iframe commet</title>
    </head>
    <body onload="Comet.initialize()">

    <script type="text/javascript">
    var Comet = {
    connection : false,
    _timer : 0,
    initialize: function() {
    if (window.ActiveXObject) {
    Comet.connection = new ActiveXObject("htmlfile");
    Comet.connection.open();
    Comet.connection.write("<html>");
    Comet.connection.write("<script>document.domain = '"+document.domain+"'");
    Comet.connection.write("</html>");
    Comet.connection.close();

    Comet.connection.parentWindow.Comet = Comet;

    var iframeEl = Comet.connection.createElement("iframe");
    Comet.connection.body.appendChild(iframeEl);

    //htmlfile中的iframe不支持对onreadystatechange的监听
    Comet._timer = setInterval(function() {
    if (iframeEl.readyState == "complete") {
    iframeEl.src = iframeEl.src;
    }
    }, 10);

    iframeEl.src = "test.php";

    } else {
    Comet.connection = document.createElement('iframe');
    Comet.connection.onload = function(){
    Comet.connection.src = Comet.connection.src;
    }
    Comet.connection.setAttribute('src','test.php');
    Comet.connection.style.display = "none";
    document.body.appendChild(Comet.connection);
    }
    },
    onMessage: function (msg) {
    document.getElementById('content').innerHTML = msg;
    },
    onUnload: function() {
    if (Comet.connection) {
    Comet.connection = false;
    }

    if (Comet._timer) {
    clearInterval(Comet._timer);
    Comet._timer = null;
    }
    }
    }

    window.onbeforeunload = function() {
    Comet.onUnload();
    }
    </script>
    <div id="content">后台返回数据</div>
    </body>
    </html>
     
     
    PHP页面的代码:
    <?php
    header("Cache-Control: no-cache, must-revalidate");
    header("Expires: Thu, 01 Jan 1970 00:00:00 GMT");
    ?>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Comet php backend</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
    <script type="text/javascript">
    var Comet = window.parent.Comet;
    </script>
    </body>
    </html>

    <?php
    date_default_timezone_set("Asia/Shanghai");

    while(1) {
    echo str_pad(' ', 4096);

    echo '<script type="text/javascript">';
    echo 'Comet.onMessage("当前服务器时间:'.date("Y-m-d H:i:s").'");';
    echo '</script>';

    ob_flush();
    flush();
    sleep(1);
    }

    ?>

    参考链接:

    1、Comet Programming:the Hidden IFrame Technique

    2、Comet Programming:Using Ajax to Simulate Server Push

    3、传说中的comet(iframe版)

    4、传说中的comet(ajax版)

    5、Browser与Server持续同步的做法介绍(Polling,Comet,Long Polling,WebSocket)

    关于Node.js的Web Socket,之前写过一篇Demo《基于Node.js的Web Socket

  • 相关阅读:
    基于 HTML5 WebGL 构建智能数字化城市 3D 全景
    基于 H5 + WebGL 实现 3D 可视化地铁系统
    基于 HTML5 WebGL 的 3D 科幻风机
    基于 HTML5 + WebGL 的太阳系 3D 展示系统
    HT Vue 集成
    基于 HTML5 + WebGL 的地铁 3D 可视化系统
    基于 HTML5 WebGL 和 VR 技术的 3D 机房数据中心可视化
    String、StringBuffer和StringBuilder的区别
    Python--Numpy基础
    python中的next()以及iter()函数
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/2129000.html
Copyright © 2020-2023  润新知