web 僞雙工(comet)全雙工(websocket)學習記錄,不要讓你的 view承受太多

寫在前頭:全部例子後臺處理都是C#代碼javascript

comet:不贅述。html

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

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

 

下面咱們就先說說這兩種模式:ajax

長輪詢模式:顧名思義,仍是輪詢模式,只不過是作了一些變異。(按照如今的流行應該是 「輪詢plus」 之類)json

首先看一下長輪詢的交互圖("引 IBM developerworks")瀏覽器

經過圖片能夠知道,流程就是  "ajax請求--》等待--》收到結果--》請求"   這樣一個輪詢過程服務器

示例代碼(js主要部分) websocket

 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

注:代碼中有不少多餘,能夠忽略

 

簡單評論一下:優勢就是一次請求,反饋結果,

缺點就是:一、這是一個同步的,因此佔用服務器資源(異步此方法就無效了)

             二、居所在IE六、七、8上會有鼠標等待狀態,視覺效果差

針對缺點2有一羣牛A想出了這樣一個辦法(本人未實驗,由於我用的是IE11)

使用 iframe 請求一個長鏈接有一個很明顯的不足之處:IE、Morzilla Firefox 下端的進度欄都會顯示加載沒有完成,並且 IE 上方的圖標會不停的轉動,表示加載正在進行;刷新當前頁面反應也是會很慢。

      解決IE的進度欄顯示加載沒有完成,可使用一個稱爲「htmlfile」的 ActiveX,是Google 的天才們使用的方法,該控件也被用到gmail+gtalk 產品中。

      修改Default.aspx的頁面代碼:

 

  <div id="con" style=" width: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>
相關文章
相關標籤/搜索