• 服务器推送技术学习(一)


    即时消息原理:

     

    当客户端发起长连接请求(轮询),服务器端监听到发现数据更新了,立即向客户端推送消息给客户端,客户监听到响应后即渲染处理展示。

    以下根据原理得出的基本方案:

    方案一:在HTML文件中加入 <META HTTP-RQUIV="Refresh" CONTENT=12>,实现刷新。这将自动指示浏览器在指定秒数之后重新装载页面。

    优点 :不需要服务器端的配置。

    缺点 :

    a) 糟糕的用户体验

    b) 对服务器的压力很大,并且造成带宽的极大浪费。

    方案一:ajax轮询或者Linux的crontab定时向服务器询问有没有新消息

    这个方案实现方法很简单,ajax轮询使用setTimeout即可实现,Linux的定时任务crontab,将需要的效果,写成脚本后配置服务器的即可,不多说。

    优点:

    a) 不需要太多服务器端的配置。

    b) 降低带宽的负荷(因为服务器返回的不是完整页面)。

    缺点:

    a) 对服务器的压力并不会有明显的减少。

    b) 实时性差,有一定的延迟。

    方案三:ajax 与 comet实现长连接

    好玩的终于来了,Comet方式通俗的说就是一种长连接机制(long lived http)。由浏览器端主动发起请求,服务器端发现数据更新后立即响应返回浏览器,它只需要连接一次,即可保持持久连接。当然comet也是会给服务器增加一定的负载,因为它一直占着连接。但也比第二种方案的性能好多。

    简单案例:

    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
    <title>Comet Test</title>
    <script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"></script>
    <script type="text/javascript">
    (function($){
       function handleResponse(response){
       $('#content').append('<div>' + response['msg'] + '</div>');
       }
     
       var timestamp = 0;
       var url = 'b.php';
       var noerror = true;
       var ajax;
     
       function connect() {
          ajax = $.ajax(url, {
             type: 'get',
             data: { 'timestamp' : timestamp },
             success: function(transport) {
                console.log(transport);
                eval('var response = '+transport);
                timestamp = response['timestamp'];
                handleResponse(response);
                noerror = true;
             },
             complete: function(transport) {
                (!noerror) && setTimeout(function(){ connect() }, 5000) || connect();
    
    //此处是轮询的关键,之后会发现其实这样的效果也不是很理想,因为每次http请求断开之后,就会启用setTimeout连接回来。优化方案见推送技术学习(二)
                noerror = false;
             }
          });
       }
     
       function doRequest(request) {
          $.ajax(url, {
             type: 'get',
             data: { 'msg' : request }
          });
       }
     
       $('#cometForm').live('submit', function(){
          doRequest($('#word').val());
          $('#word').val('');
          return false;
       });
     
       $(document).ready(function(){
          connect();
       });
    })(jQuery);
    </script>
    <div id="content"></div>
    <div style="margin: 5px 0;">
    <form action="javascript:void(0);" id="cometForm" method="get">
    <input id="word" name="word" type="text" value="">
    <input name="submit" type="submit" value="Send">
     
    </form></div>
    

      

     

     服务器端处理:

    <?php
     
    $filename  = dirname(__FILE__).'/data.txt';
     
    // 消息都储存在这个文件中
    $msg = isset($_GET['msg']) ? $_GET['msg'] : '';
     
    if ($msg != ''){
       file_put_contents($filename,$msg);
       die();
    }
     
    // 不停的循环,直到储存消息的文件被修改 ,用数据库也类似这样
    
    $lastmodif    = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
    $currentmodif = filemtime($filename);
    
    $response = array();
    while ($currentmodif <= $lastmodif){ // 如果数据文件已经被修改
       $currentmodif = filemtime($filename);
    
    // 返回json数组
    
    $response['msg']       = file_get_contents($filename);
    $response['timestamp'] = $currentmodif;
    echo json_encode($response);
    
    Ob_flush();
    flush();//这里是comet推送技术核心,必须让请求的内容马上推送出去,不等待页面加载完成,即将内容从缓存中冲刷出来 
    usleep(100000); // 100ms暂停 缓解CPU压力
    
    }
     
    ?>
    

    关于推送消息本人也在学习研究中,有更好的想法可以留言互相交流(gan<1976741895@qq.com>)。

  • 相关阅读:
    css 选择器
    用 jupyter notebook 打开 oui.txt 文件出现的问题及解决方案
    jupyter notebook 中用 matplot 画图不显示图像
    dropna(thresh=n) 的用法
    pandas 对象中 to_pickle 方法参数命名问题,不能用frame
    Index.get_indexer 方法的含义
    7)微分
    5)函数极限与连续函数
    3)数据科学的数学之序列与极限--阶乘/指数增长比较
    2)数据科学的数学之序列与极限
  • 原文地址:https://www.cnblogs.com/lihuobao/p/5518053.html
Copyright © 2020-2023  润新知