1.什么是COMET ?

          查閱詞典Comet中文是“彗星”的意思,起初我見到這個單詞的時候,我就猜想優美名字背后到底是什么呢?他是一種WEB服務器推的應用技術(Server Push)。Server Push就如同它自己的名字一樣,將更多華麗的web體驗“推”進了我們的視野。有
          一些觀點 將Comet比作是 Ajax 的接班人,這個觀點 我無法茍同,我認為Ajax  與Comet 并不存在取代關系。 從實質上講 Comet 還是Ajax的應用。

          要講清楚Comet是什么的問題?我不妨將話題扯遠點,我們先了解下web開發的歷史。

          大家一定還記得從前,我們在論壇注冊賬號,一點了提交按鈕,頁面就一片空白(服務器在刷新頁面,處理提交數據),ie的狀態圖就不停的轉,一個提交按鈕一點,頁面就再也不能進行其他操作了(因為這里的數據請求和界面操作是同步的)。我們就傻等著服務器處理完數據后返回,以前網速也慢,服務器性能也差。那么這個等待時間就會挑戰大家的容忍極限。這個就是Ajax誕生要解決的問題。

          其實在Ajax這個名字沒有出現的時候,‘Ajax’的應用就已經存在了。那時前輩們就已經在WEB方面為追求更完美的用戶體驗,為追求異步通信,為追求局部刷新摸索出了一些可重用的方式方法。大致方法有2種:

          一種是頁面中放入一個隱藏的frame 頁面,這個頁面有一個表單form對象。而數據的提交,就交給這個 frame 頁面。就算是刷新也是這個頁面刷新,而這個頁面由于是隱藏的或者高度和寬度設置為0的,所以刷新時候用戶感覺不到。那么當數據返回的時候也就能夠達到局部刷新的效果。而且用戶操作的頁面不用被卡住,這樣也達到異步通信的效果了。這種是比較古老和麻煩的方法。

          另外一種和當今的Ajax就很類似了。開發人員開發自己的ActiveX 控件,這個控件的功能基本和現在Ajax 差不多,其實Ajax 大家也可以看成是一個ActiveX 控件,只是各大瀏覽器都實現了這個ActiveX 控件。所以現在我們開發Ajax應用,不用自己開發這個ActiveX 控件。

           

            Ajax實現了對XMLHTTP對象的封裝,這個對象有一系列接口,比較重要的是發送異步數據的接口。


          2.那Comet是在什么歷史背景下誕生的呢?


          當服務器端數據發生變化時,客戶端如何即時得到通知呢?這個就是Comet誕生的背景。

          1.  傳統方法定時刷新,就是隔一個時間段瀏覽器刷新一次。(沒有用戶受得了這種方法,服務器也害怕遇到這種事情)

          2.  長輪詢(long-polling)

          Ajax隔一段時間就去服務器查詢是否有更新,但是多長時間去查詢成了問題。因為性能和即時性造成了嚴重的反比關系。

          3.在前面兩種方法被否定后,想到了服務器推送至客戶端這種模式,但是web開發客戶端是一個瀏覽器(并不是我們自己控制的GUI客戶端)。所以Comet登場,簡單說還是利用Ajax與服務器建立http長連接查詢是否有數據更新,服務器收到一個連接如果沒有數據更新就阻塞這個連接不要返回給客戶端,直到有新數據再返回給客戶端。Web客戶端,發起的連接一旦被返回,或者超時就再次建立http長連接。這樣就能保證數據的即時更新,以及盡量減少服務器的計算工作。 2.  Comet的一些應用 

            目前Comet主要應用在一些股票web客戶端,以及一些基于web的即時聊天系統中。

          比較成熟的框架有Dojo ,Dwr 等一些Ajax框架中實現了該功能。 
          3. Comet  優、 缺點  

          3.1 缺點  

          長期占用連接,喪失了無狀態高并發的特點。

          server push不會是一個沒有副作用的解決方案,是否適合還要仔細權衡。

          3.2 優點  

          Ø  實時性好(消息延時小)

          Ø  性能好(能支持大量用戶)
           4.其他服務器推技術

          Comet 只是眾多服務器推技術中的一種,目前市面上還有許多其他流行服務器推技術。
          4.1  Flash XMLSocket   

          這種方案實現的基礎是:

          1. Flash 提供了 XMLSocket 類。

          2. JavaScript 和 Flash 的緊密結合:在 JavaScript 可以直接調用 Flash 程序提供的接口。

          但此方案的缺點在于:

          1. 因為 XMLSocket 沒有 HTTP 隧道功能,XMLSocket 類不能自動穿過防火墻;

          2. 因為是使用套接口,需要設置一個通信端口,防火墻、代理服務器也可能對非 HTTP 通道端口進行限制;

          不過這種方案在一些網絡聊天室,網絡互動游戲中已得到廣泛使

          4.2  Java Applet 套接口   

          在客戶端使用 Java Applet,通過  java.net.Socket  或  java.net.DatagramSocket  或  java.net.MulticastSocket  建立與服務器端的套接口連接,從而實現“服務器推”。

          這種方案最大的不足在于 Java applet  需要客戶端安裝JAVA虛擬機
          5. 總結
            

          Comet  不存在什么新技術,沒有什么神秘可言 瓶頸主要集中在web server這一塊,一般成熟的 Comet  商業應用都會有一套它自己專用的web server,比如lightstreamer就是這樣! 



          實例解析:

          服務端:
          <?php
          $filename  = dirname(__FILE__).'/data.txt';
          $msg = isset($_GET['msg']) ? $_GET['msg': '';
          if ($msg != '')
          {
              
          //寫入內容至文件
              file_put_contents($filename,$msg);
              
          die();
          }
          set_time_limit(0);
          $lastmodif    = isset($_GET['timestamp']) ? $_GET['timestamp': 0;

          //取得文件最后修改時間
          $currentmodif = filemtime($filename);

          while ($currentmodif <= $lastmodif
          {    
              
          //有釋放CPU占用率的作用
                usleep(10000); 
                
          //清除文件緩存信息
                clearstatcache();
                
          $currentmodif = filemtime($filename);
          }

          // return a json array
          $response = array();
          $response['msg']       = file_get_contents($filename);
          $response['timestamp'= $currentmodif;
          echo json_encode($response);
          ob_flush();
          flush();
          ?>

          客戶端:
          onComplete: function(transport) 
                      {
                     
          if (!WebApp._noerror_)
                          {
                              setTimeout(WebApp.WebMain, 
          5000); 
                          }
          else
                              { 
                              setTimeout(WebApp.WebMain, 
          10); 
                          }
                          WebApp._noerror_ 
          = false;
                        }

          可以看到不管成功失敗都將開始一次新的ajax請求。也就是保持了連接。

          使用方法:

          1.需要php服務器;

          2.開兩個不同瀏覽器即可掩飾效果。

          這只是一個介紹原理型demo,請勿商業使用。


          DEMO下載
          posted on 2009-04-13 11:37 -274°C 閱讀(29005) 評論(11)  編輯  收藏 所屬分類: PHPweb前端


          FeedBack:
          # re: 淺談comet技術
          2009-04-14 00:16 | 閑人
          這實質還是http請求,客戶端不會因為長久沒收到應答而斷開連接嗎  回復  更多評論
            
          # re: 淺談comet技術
          2009-04-14 09:10 | HiMagic!
          @閑人
          會,就算超時,再連就是了,這樣的場景適用于console數量可控的case。  回復  更多評論
            
          # re: 淺談comet技術[未登錄]
          2009-04-14 09:24 | -274°C
          @HiMagic!

          贊同。  回復  更多評論
            
          # re: 淺談comet技術[未登錄]
          2010-07-21 15:31 | cc
          本片文章有兩個地方講的錯了
          1. 關于 comet
          commet 有兩種實現方式:
          一、 基于 AJAX 的長輪詢方式
          二、 基于 iframe 及 htmlfile 的流方式
          在本篇文中中說到是第一種,開源的pushlet框架都支持這兩種方式。

          2. 對 AJAX 的長輪詢的理解
          AJAX 的長輪詢指的是: ajax提交請求,服務器端會阻塞請求直到有數據傳遞或超時才返回。客戶端 JavaScript 響應處理函數會在處理完服務器返回的信息后,再次發出請求,重新建立連接。本文中說的“長輪詢”是傳統的ajax使用方式,不是現在說的長輪詢  回復  更多評論
            
          # re: 淺談comet技術
          2010-09-07 13:11 | 工夫茶
          最近在學Comet方面的知識,你的例子對我有很大幫助,我想知道更多關于comet方面的知識  回復  更多評論
            
          # re: 淺談comet技術
          2012-12-13 14:47 | 555
          asd  回復  更多評論
            
          # re: 淺談comet技術
          2013-08-26 11:20 | 星夜
          comet和webSocket相比哪個好呢?  回復  更多評論
            
          # re: 淺談comet技術
          2013-09-05 11:43 | 過的地方
          @星夜
          webSocket要求瀏覽器更高的版本。  回復  更多評論
            
          # re: 淺談comet技術
          2014-03-06 10:23 | chenglin博客
          了解,學習了,  回復  更多評論
            
          # re: 淺談comet技術
          2014-05-18 15:57 | hello world
          thank you  回復  更多評論
            
          # re: 淺談comet技術
          2014-11-18 15:36 | harlan
          slowhttp攻擊會直接把server搞垮 因為通常這種應用場景的http的timeout值會比較大  回復  更多評論
            

          常用鏈接

          留言簿(21)

          隨筆分類(265)

          隨筆檔案(242)

          相冊

          JAVA網站

          關注的Blog

          搜索

          •  

          積分與排名

          • 積分 - 914107
          • 排名 - 40

          最新評論

          主站蜘蛛池模板: 车致| 泊头市| 乌兰浩特市| 留坝县| 普定县| 溧水县| 呼伦贝尔市| 吴江市| 阜宁县| 威海市| 泸州市| 山阳县| 吉木萨尔县| 克拉玛依市| 清河县| 沧源| 司法| 黎平县| 布拖县| 衡南县| 天柱县| 得荣县| 驻马店市| 沂南县| 满城县| 砚山县| 寻乌县| 怀远县| 东乡族自治县| 丰宁| 浦城县| 博湖县| 南召县| 普洱| 丹阳市| 纳雍县| 沾益县| 城市| 奈曼旗| 吉安市| 民县|