1.什么是COMET ?

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

          要講清楚Comet是什么的問(wèn)題?我不妨將話題扯遠(yuǎn)點(diǎn),我們先了解下web開(kāi)發(fā)的歷史。

          大家一定還記得從前,我們?cè)谡搲?cè)賬號(hào),一點(diǎn)了提交按鈕,頁(yè)面就一片空白(服務(wù)器在刷新頁(yè)面,處理提交數(shù)據(jù)),ie的狀態(tài)圖就不停的轉(zhuǎn),一個(gè)提交按鈕一點(diǎn),頁(yè)面就再也不能進(jìn)行其他操作了(因?yàn)檫@里的數(shù)據(jù)請(qǐng)求和界面操作是同步的)。我們就傻等著服務(wù)器處理完數(shù)據(jù)后返回,以前網(wǎng)速也慢,服務(wù)器性能也差。那么這個(gè)等待時(shí)間就會(huì)挑戰(zhàn)大家的容忍極限。這個(gè)就是Ajax誕生要解決的問(wèn)題。

          其實(shí)在Ajax這個(gè)名字沒(méi)有出現(xiàn)的時(shí)候,‘Ajax’的應(yīng)用就已經(jīng)存在了。那時(shí)前輩們就已經(jīng)在WEB方面為追求更完美的用戶體驗(yàn),為追求異步通信,為追求局部刷新摸索出了一些可重用的方式方法。大致方法有2種:

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

          另外一種和當(dāng)今的Ajax就很類似了。開(kāi)發(fā)人員開(kāi)發(fā)自己的ActiveX 控件,這個(gè)控件的功能基本和現(xiàn)在Ajax 差不多,其實(shí)Ajax 大家也可以看成是一個(gè)ActiveX 控件,只是各大瀏覽器都實(shí)現(xiàn)了這個(gè)ActiveX 控件。所以現(xiàn)在我們開(kāi)發(fā)Ajax應(yīng)用,不用自己開(kāi)發(fā)這個(gè)ActiveX 控件。

           

            Ajax實(shí)現(xiàn)了對(duì)XMLHTTP對(duì)象的封裝,這個(gè)對(duì)象有一系列接口,比較重要的是發(fā)送異步數(shù)據(jù)的接口。


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


          當(dāng)服務(wù)器端數(shù)據(jù)發(fā)生變化時(shí),客戶端如何即時(shí)得到通知呢?這個(gè)就是Comet誕生的背景。

          1.  傳統(tǒng)方法定時(shí)刷新,就是隔一個(gè)時(shí)間段瀏覽器刷新一次。(沒(méi)有用戶受得了這種方法,服務(wù)器也害怕遇到這種事情)

          2.  長(zhǎng)輪詢(long-polling)

          Ajax隔一段時(shí)間就去服務(wù)器查詢是否有更新,但是多長(zhǎng)時(shí)間去查詢成了問(wèn)題。因?yàn)樾阅芎图磿r(shí)性造成了嚴(yán)重的反比關(guān)系。

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

            目前Comet主要應(yīng)用在一些股票web客戶端,以及一些基于web的即時(shí)聊天系統(tǒng)中。

          比較成熟的框架有Dojo ,Dwr 等一些Ajax框架中實(shí)現(xiàn)了該功能。 
          3. Comet  優(yōu)、 缺點(diǎn)  

          3.1 缺點(diǎn)  

          長(zhǎng)期占用連接,喪失了無(wú)狀態(tài)高并發(fā)的特點(diǎn)。

          server push不會(huì)是一個(gè)沒(méi)有副作用的解決方案,是否適合還要仔細(xì)權(quán)衡。

          3.2 優(yōu)點(diǎn)  

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

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

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

          這種方案實(shí)現(xiàn)的基礎(chǔ)是:

          1. Flash 提供了 XMLSocket 類。

          2. JavaScript 和 Flash 的緊密結(jié)合:在 JavaScript 可以直接調(diào)用 Flash 程序提供的接口。

          但此方案的缺點(diǎn)在于:

          1. 因?yàn)?nbsp;XMLSocket 沒(méi)有 HTTP 隧道功能,XMLSocket 類不能自動(dòng)穿過(guò)防火墻;

          2. 因?yàn)槭鞘褂锰捉涌冢枰O(shè)置一個(gè)通信端口,防火墻、代理服務(wù)器也可能對(duì)非 HTTP 通道端口進(jìn)行限制;

          不過(guò)這種方案在一些網(wǎng)絡(luò)聊天室,網(wǎng)絡(luò)互動(dòng)游戲中已得到廣泛使

          4.2  Java Applet 套接口   

          在客戶端使用 Java Applet,通過(guò)  java.net.Socket  或  java.net.DatagramSocket  或  java.net.MulticastSocket  建立與服務(wù)器端的套接口連接,從而實(shí)現(xiàn)“服務(wù)器推”。

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

          Comet  不存在什么新技術(shù),沒(méi)有什么神秘可言 瓶頸主要集中在web server這一塊,一般成熟的 Comet  商業(yè)應(yīng)用都會(huì)有一套它自己專用的web server,比如lightstreamer就是這樣! 



          實(shí)例解析:

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

          //取得文件最后修改時(shí)間
          $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;
                        }

          可以看到不管成功失敗都將開(kāi)始一次新的ajax請(qǐng)求。也就是保持了連接。

          使用方法:

          1.需要php服務(wù)器;

          2.開(kāi)兩個(gè)不同瀏覽器即可掩飾效果。

          這只是一個(gè)介紹原理型demo,請(qǐng)勿商業(yè)使用。


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


          FeedBack:
          # re: 淺談comet技術(shù)
          2009-04-14 00:16 | 閑人
          這實(shí)質(zhì)還是http請(qǐng)求,客戶端不會(huì)因?yàn)殚L(zhǎng)久沒(méi)收到應(yīng)答而斷開(kāi)連接嗎  回復(fù)  更多評(píng)論
            
          # re: 淺談comet技術(shù)
          2009-04-14 09:10 | HiMagic!
          @閑人
          會(huì),就算超時(shí),再連就是了,這樣的場(chǎng)景適用于console數(shù)量可控的case。  回復(fù)  更多評(píng)論
            
          # re: 淺談comet技術(shù)[未登錄](méi)
          2009-04-14 09:24 | -274°C
          @HiMagic!

          贊同。  回復(fù)  更多評(píng)論
            
          # re: 淺談comet技術(shù)[未登錄](méi)
          2010-07-21 15:31 | cc
          本片文章有兩個(gè)地方講的錯(cuò)了
          1. 關(guān)于 comet
          commet 有兩種實(shí)現(xiàn)方式:
          一、 基于 AJAX 的長(zhǎng)輪詢方式
          二、 基于 iframe 及 htmlfile 的流方式
          在本篇文中中說(shuō)到是第一種,開(kāi)源的pushlet框架都支持這兩種方式。

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

          常用鏈接

          留言簿(21)

          隨筆分類(265)

          隨筆檔案(242)

          相冊(cè)

          JAVA網(wǎng)站

          關(guān)注的Blog

          搜索

          •  

          積分與排名

          • 積分 - 916102
          • 排名 - 40

          最新評(píng)論

          主站蜘蛛池模板: 唐河县| 红安县| 中江县| 饶河县| 伊春市| 大兴区| 江孜县| 宿迁市| 沛县| 江安县| 巴林左旗| 三都| 徐水县| 颍上县| 顺昌县| 内乡县| 丰城市| 高碑店市| 东台市| 开封市| 沛县| 囊谦县| 琼海市| 莲花县| 丹凤县| 武穴市| 开化县| 博湖县| 灵山县| 平遥县| 望谟县| 宝应县| 阳朔县| 永济市| 凤阳县| 绩溪县| 明光市| 万载县| 京山县| 布拖县| 冕宁县|