• [置顶]web 伪双工(comet)全双工(websocket)学习记录,不要让你的 view承受太多


    写在前头:所有例子后台处理都是C#代码

    comet:不赘述。

    http://www.ibm.com/developerworks/cn/web/wa-lo-comet/

    http://zh.wikipedia.org/wiki/Comet_(web%E6%8A%80%E6%9C%AF)

    下面我们就先说说这两种模式:

    长轮询模式:顾名思义,还是轮询模式,只不过是做了一些变异。(按照现在的流行应该是 “轮询plus” 之类)

    首先看一下长轮询的交互图("引 IBM developerworks")

    通过图片可以知道,流程就是  "ajax请求--》等待--》收到结果--》请求"   这样一个轮询过程

    示例代码(js主要部分) 

     1  function webApply() {
     2             $.ajax({
     3                 url: '你的目标url',
     4                 type: 'post',//get...
     5                 dataType:'json',//或者其他什么
     6                 success: function (data) {
     7                     //处理逻辑
     8 
     9                     //继续请求
    10                     webApply();
    11                 },
    12                 error: function (data, status) {
    13                     //错误处理
    14                 }
    15             })
    16         }
    View Code

    实例代码(这个地方我就给一个连接吧)

    http://msdn.microsoft.com/zh-cn/library/ms227433(v=VS.90).aspx

    注:其实不一定要异步,同步也可以,只是在服务器的消耗上有一点点区别。

    简单评论一下:这样做的优点就是减少了轮询请求次数。节约了一定的资源(网络,服务器),但是缺点就是还是一个轮询法,没有实现长连接,也就是无法记录每一次请求的状态。每一次请求都是一次新的访问,一些实例对象无法共享,只能借助session对象。

    再看一下第二种模式

    iframe+服务:这种模式其实也不能算是长连接,是利用了iframe的异步请求效果。

    这个就直接上代码

    示例代码(html主要部分)

    <iframe src="你的服务代码" id="importDate" name="importDate" style="display: none"></iframe>

    就这样简单语句

    服务器端代码

     1 //Handler请求入口
     2  public void ProcessRequest(HttpContext context)
     3         {
     4             context.Response.ContentType = "text/html;charset=utf-8";
     5             //开始执行操作
     6             ExcelImport.Instance.Action(context);
     7         }
     8 
     9     internal class ExcelImport
    10     {
    11         private readonly static ExcelImport excelimport = new ExcelImport();
    12         internal static ExcelImport Instance
    13         {
    14             get { return excelimport; }
    15         }
    16         string o = string.Empty;
    17         //读取excel文件框架
    18         internal bool ReadExcelFreamwork(HttpContext context)
    19         {
    20             Thread.Sleep(3000);
    21             o = "正在读取框架";
    22             ThreadPool.QueueUserWorkItem(new WaitCallback(xx => {
    23                 context.Response.Write("<script language='javascript' type='text/javascript'>parent.dis('" + o + "');</script>");
    24                 context.Response.Flush();
    25             }));           
    26             return true;
    27         }
    28         //验证excel框架
    29         internal bool VaildateExcelFreamwork(HttpContext context)
    30         {
    31             Thread.Sleep(3000);
    32             o = "正在验证框架";
    33             ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>
    34             {
    35                 context.Response.Write("<script language='javascript' type='text/javascript'>parent.dis('" + o + "');</script>");
    36                 context.Response.Flush();
    37             }));  
    38             return true;
    39         }
    40         //读取数据
    41         internal bool ReadData(HttpContext context)
    42         {
    43             Thread.Sleep(3000);
    44             o = "正在读取数据";
    45             ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>
    46             {
    47                 context.Response.Write("<script language='javascript' type='text/javascript'>parent.dis('" + o + "');</script>");
    48                 context.Response.Flush();
    49             }));  
    50             return true;
    51         }
    52         //验证数据
    53         internal bool ValidateData(HttpContext context)
    54         {
    55             Thread.Sleep(3000);
    56             o = "正在验证数据";
    57             ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>
    58             {
    59                 context.Response.Write("<script language='javascript' type='text/javascript'>parent.dis('" + o + "');</script>");
    60                 context.Response.Flush();
    61             }));  
    62             return true;
    63         }
    64         //导入数据
    65         internal bool ImportData(HttpContext context)
    66         {
    67             Thread.Sleep(3000);
    68             o = "正在导入数据";
    69             ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>
    70             {
    71                 context.Response.Write("<script language='javascript' type='text/javascript'>parent.dis('" + o + "');</script>");
    72                 context.Response.Flush();
    73             }));  
    74             return true;
    75         }
    76 
    77         internal bool Finsh(HttpContext context)
    78         {
    79             Thread.Sleep(3000);
    80             o = "finsh";
    81             ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>
    82             {
    83                 context.Response.Write("<script language='javascript' type='text/javascript'>parent.dis('" + o + "');</script>");
    84                 context.Response.Flush();
    85             }));  
    86             return true;
    87         }
    88 
    89         internal void Action(object o)
    90         {
    91             HttpContext context = (HttpContext)o;
    92             ReadExcelFreamwork(context);
    93             VaildateExcelFreamwork(context);
    94             ReadData(context);
    95             ValidateData(context);
    96             ImportData(context);
    97             Finsh(context);
    98         }
    99     }
    View Code

    注:代码中有很多多余,可以忽略

    简单评论一下:优点就是一次请求,反馈结果,

    缺点就是:1、这是一个同步的,所以占用服务器资源(异步此方法就无效了)

                 2、居所在IE6、7、8上会有鼠标等待状态,视觉效果差

    针对缺点2有一群牛A想出了这样一个办法(本人未实验,因为我用的是IE11)

    使用 iframe 请求一个长连接有一个很明显的不足之处:IE、Morzilla Firefox 下端的进度栏都会显示加载没有完成,而且 IE 上方的图标会不停的转动,表示加载正在进行;刷新当前页面反应也是会很慢。

          解决IE的进度栏显示加载没有完成,可以使用一个称为“htmlfile”的 ActiveX,是Google 的天才们使用的方法,该控件也被用到gmail+gtalk 产品中。

          修改Default.aspx的页面代码:

      <div id="con" style=" 400; height:200px; border:1px solid #FF0">
       </div>
        <script type="text/javascript">
            function getData(d)
            {
                $("#con").append(d);
            }
     
            function rpc_iframe() {
                var transferDoc = new ActiveXObject("htmlfile");
                transferDoc.open();
                transferDoc.write("<html>")
                transferDoc.write("<div><iframe src="Flush.aspx"></iframe></div>");
                transferDoc.close("</html>");
                transferDoc.parentWindow.getData = getData;
                setInterval(function () { }, 10000);  //不加这句会使连接断开
            }
     
            rpc_iframe();
       </script>

    好了,下面我就在学一学websocket吧,HTML5的新特性,多么令人激动的事情,可是,可但是有些浏览器就是成长的这么慢

    吼吼,马上下班了  先mark个地址,所有在学吧

    https://developer.mozilla.org/zh-CN/docs/WebSockets

       <script type="text/javascript">
     var websocket;
     var connected = false;
     function doConnect(wsURI)
     {
         if (connected) {
             debug_output_f("<span style='color:red;'>You're already connected!</span>");
         } else {
             websocket = new WebSocket(wsURI);
             websocket.onopen = function(evt) { onOpen(evt) };
             websocket.onclose = function(evt) { onClose(evt) };
             websocket.onmessage = function(evt) { onMessage(evt) };
             websocket.onerror = function(evt) { onError(evt) };
             debug_output_f("CONNECTION REQUESTED ....");
         }
     }
     function onOpen (evt) {
         connected = true;
         debug_output_f("CONNECTED");
     }
     function onClose (evt) {
         connected = false;
         websocket.close();
         debug_output_f("DISCONNECTED");
     }
     function onMessage (evt) {
         debug_output_f("<span style='color: blue;'>RESP: " + evt.data + "</span>");
     }
     function onError (evt) {
       debug_output_f("<span style='color:red;'>ERROR:</span> " + evt.data);
     }
     function doSend (msg)
     {
         if (connected) {
             websocket.send(msg);
             debug_output_f("SENT: " + msg);
             /*
             { // binary
                 size = msg.length;
                 var ba = new Uint8Array(size);
                 for (var i=0; i<size; i++) {
                     ba[i] = msg.charCodeAt(i);
                 }
                 m = ba.buffer;
                 websocket.send(m);
                 debug_output_f("SENT: binary message");
             }
             */
         } else {
             debug_output_f("<span style='color: red;'>NOT CONNECTED: No message sent.</span>");
         }
     }
     function doClose () {
         if (connected) {
             debug_output_f("CLOSING ....");
             websocket.close();
             connected=false;
         } else {
             debug_output_f("<span style='color: red;'>NOT CONNECTED</span>");
         }
     }
                 </script>
     
    
    
  • 相关阅读:
    RESTful风格的API
    案例:toDoList
    jQuery中的Ajax
    php 使用kafka
    crontab不执行
    php两种实现守护进程的方式
    crontab不执行脚本,手动调测又没有任何问题
    centos7 安装跳板机(堡垒机)
    Ubuntu修改默认键盘布局的方法
    openresty nginx升级版
  • 原文地址:https://www.cnblogs.com/xiaoch/p/13417953.html
Copyright © 2020-2023  润新知