隨筆-124  評論-194  文章-0  trackbacks-0

          DWR2.0的推技術:這里有介紹

          comet的實現介紹:這里

          其中的原理在于維護HTTP長連接,這里有介紹

           

          摘錄一部分,說明其原理:

          Pushlet基于HTTP流,這種技術常常用在多媒體視頻、通訊應用中,比如QuickTime。與裝載HTTP頁面之后馬上關閉HTTP連接的做法相反,Pushlet采用HTTP流方式將新數據源源不斷地推送到client,再此期間HTTP連接一直保持打開。有關如何在Java中實現這種Keep-alive的長連接請參看Sun提供的《HTTP Persistent Connection》W3C的《HTTP1.1規范》。
          示例1
                  我們利用HTTP流開發一個JSP頁面(因為它易于部署,而且它在web server中也是作為servlet對待的),此頁面在一個定時器循環中不斷地發送新的HTML內容給client:


          <%
            int i = 1;
              
            try {
              while (true) {
                 out.print("<h1>"+(i++)+"</h1>");
                 out.flush();
                
                 try {
                      Thread.sleep(3000);
                 } catch (InterruptedException e) {
                 out.print("<h1>"+e+"</h1>");
                  }
               }
             } catch (Exception e) {
                 out.print("<h1>"+e+"</h1>");
             }
          %>

                  在Pushlet源代碼中提供了此頁面(examples/basics/push-html-stream.jsp)。上面的頁面并不是十分有用,因為在我們刷新頁面時,新內容機械地、持續不斷地被添加到頁面中,而不是server端更新的內容。
          示例2
                  現在讓我們步入Pushlet工作機理中一探究竟。通過運行Pushlet的示例源代碼(examples/basics/ push-js-stream.html),我們會看到這個每3秒刷新一次的頁面。那么它是如何實現的呢?
                  此示例中包含了三個文件:push-js-stream.html、push-js-stream-pusher.jsp、push-js-stream-display.html。
                  其中push-js-stream.html是主框架文件,它以HTML Frame的形式包含其它兩個頁面。
                  push-js-stream-pusher.jsp是一個JSP,它執行在server端,此文件內容如下:

            7: <%
            8:   /** Start a line of JavaScript with a function call to parent frame. */
            9:   String jsFunPre = "<script language=JavaScript >parent.push('";
          10:  
          11:   /** End the line of JavaScript */
          12:   String jsFunPost = "')</script> ";
          13:  
          14:   int i = 1;
          15:   try {
          16:  
          17:     // Every three seconds a line of JavaScript is pushed to the client
          18:     while (true) {
          19:    
          20:        // Push a line of JavaScript to the client
          21:        out.print(jsFunPre+"Page "+(i++)+jsFunPost);
          22:        out.flush();
          23:        
          24:        // Sleep three secs
          25:        try {
          26:             Thread.sleep(3000);
          27:        } catch (InterruptedException e) {
          28:             // Let client display exception
          29:             out.print(jsFunPre+"InterruptedException: "+e+jsFunPost);
          30:        }
          31:      }
          32:    } catch (Exception e) {
          33:             // Let client display exception
          34:             out.print(jsFunPre+"Exception: "+e+jsFunPost);
          35:    }
          36: %>

          注意在示例1和示例2中使用JSP時都存在一個問題:一些servlet引擎在某個client離開時會“吃掉”IOException,以至于JSP頁面將永不拋出此異常。所以在這種情況下,頁面循環將會永遠執行下去。而這正是Pushlet實現采用servlet的原因之一:可以捕獲到IOException。
                  在上面代碼的第21行中可以看到在一個定時器循環(3秒/周期)中打印了一些HTML并將它們輸出到client瀏覽器。請注意,這里推送的并非HTML而是Javascript!這樣做的意義何在?
                  它把類似“<script language=JavaScript >parent.push('Page 4')</script>”的一行代碼推送到瀏覽器;而具有JavaScript引擎的瀏覽器可以直接執行收到的每一行代碼,并調用parent.push()函數。而代碼中的Parent便是瀏覽器頁面中所在Frame的Parent,也就是push-js-stream.html。讓我們看看都發生了什么?

          <script LANGUAGE="JavaScript">
          var pageStart="<HTML><HEAD></HEAD><BODY BGCOLOR=blue TEXT=white><H2>Server pushes: <para>";
          var pageEnd="</H2></BODY></HTML>";
            // Callback function with message from server.
            // This function is called from within the hidden JSP pushlet frame
            function push(content) {

              // Refresh the display frame with the content received
              window.frames['displayFrame'].document.writeln(pageStart+content+pageEnd);
              window.frames['displayFrame'].document.close();
            }

          </script>



               <!-- frame to display the content pushed by the pushlet -->
              
              
               <!-- Hidden frame with the pushlet that pushes lines of JavaScript-->
              
          </FRAMESET>

                  可以看到push-js-stream.html中的push()函數被名為pushletFrame的JSP Frame調用:把傳入的參數值寫入到displayFrame(此Frame為push-js-stream-display.html)。這是動態HTML的一個小技巧:使用document對象的writeln方法刷新某個Frame或者Window的內容。
                  于是displayFrame成為了用于顯示內容的、真正的視圖。displayFrame初始化為黑色背景并顯示“wait…”直到來自server的內容被推送過來:

          <H1>WAIT...</H1>

                  這便是Pushlet的基本做法:我們從servlet(或者從示例中的JSP)把JavaScript代碼作為HTTP流推送到瀏覽器。這些代碼被瀏覽器的JavaScript引擎解釋并完成一些有趣的工作。于是便輕松地完成了從server端的Java到瀏覽器中的JavaScript的回調。
                  上面的示例展示了Pushlet原理,但這里存在一些等待解決的問題和需要增添的特性。于是我建立了一個小型的server端Pushlet框架(其類結構圖表將會展示在下面),添加了一些用在client中的JavaScript庫。由于client需要依賴更多的DHTML特性(比如Layers),我們將首先粗略地溫習一些DHTML知識。示例代碼見examples/dhtml。
          posted on 2007-07-03 18:10 我愛佳娃 閱讀(2329) 評論(0)  編輯  收藏 所屬分類: web技術
          主站蜘蛛池模板: 霍州市| 巧家县| 开平市| 桂阳县| 安图县| 织金县| 且末县| 陵水| 宿松县| 衡阳市| 富宁县| 剑阁县| 武定县| 黄梅县| 民权县| 大安市| 曲麻莱县| 玛沁县| 乐山市| 即墨市| 锡林郭勒盟| 陵川县| 正宁县| 自治县| 崇明县| 贵阳市| 沁水县| 江门市| 嘉峪关市| 吉首市| 汉阴县| 商都县| 枞阳县| 咸丰县| 九龙县| 潞西市| 天峨县| 昆明市| 韶关市| 金堂县| 太白县|