隨筆-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技術
          主站蜘蛛池模板: 红安县| 大邑县| 贵州省| 宜宾县| 丘北县| 遂溪县| 阿拉善右旗| 江西省| 黄石市| 崇州市| 维西| 祁连县| 乌审旗| 库伦旗| 清流县| 卢湾区| 武安市| 乌海市| 侯马市| 建昌县| 华阴市| 金门县| 承德县| 米易县| 正蓝旗| 榆中县| 牡丹江市| 陆良县| 苏尼特右旗| 阜平县| 云安县| 博湖县| 灵寿县| 黄石市| 三亚市| 阿拉尔市| 额尔古纳市| 广宁县| 青川县| 平舆县| 合川市|