Comet指一種更高級的Ajax技術( 也稱 「服務器推送」 ),一種服務器向頁面推送數據的技術。Comet可以讓信息近乎實時地被推送到頁面上,很是適合體育比賽的分數和股票報價。
有兩種實現Comet的方式:長輪詢、流
傳統輪詢(也稱短輪詢),即瀏覽器定時向服務器發送請求,看有沒有更新的數據。
長輪詢把短輪詢顛倒了一下。頁面發起一個到服務器的新請求,而後服務器一直保持鏈接打開,直到有數據可發送。發送完數據以後,瀏覽器關閉鏈接,隨即又發送一個到服務器的新請求。這一過程在頁面打開期間一直持續不斷。
輪詢的優點是全部瀏覽器都支持,由於使用XHR對象和setTimeout()就能實現。而你要作的就是決定何時發送請求。
HTTP流,在頁面的整個生命週期內只使用一個HTTP鏈接。瀏覽器向服務器發送一個請求,而服務器保持鏈接打開,而後週期性地向瀏覽器發送數據。
如,下面這段PHP腳本就是採用流實現的服務器中常見的形式:
1 <?php 2 $i = 0; 3 while(true){ 4 //輸出一些數據,而後當即刷新輸出緩存 5 echo "Number is $i"; 6 flush(); 7 //等幾秒鐘 8 sleep(10); 9 $i++; 10 } 11 ?>
全部服務器語言都支持打印到輸出緩存而後刷新(將輸出緩存中的內容一次性所有發送到客戶端)的功能。而這正是實現HTTP流的關鍵所在。
Firefox、Safari、Opera、Chrome中,經過偵聽readystatechange事件及檢測readyState的值是否爲3,就能夠利用XHR對象實現HTTP流。隨着不斷從服務器接收數據,readyState的值會週期性地變爲3,。當readyState值變爲3時,responseText屬性就會保存接收到的全部數據。此時,比較此前接收到的數據,決定從什麼位置開始取得最新的數據。使用XHR對象實現HTTP流的典型代碼:
1 function createStreamingClient(url, progress, finished){ 2 var xhr = new XMLHttpRequest(), 3 received = 0; 4 xhr.open("get, url, true"); 5 xhr.onreadystatechange = function(){ 6 var result; 7 if(xhr.readyState ==3){ 8 //只取得最新數據並調整計數器 9 result = xhr.responseText.substring(received); 10 received += result.length; 11 //調用progress回調函數 12 progress(result); 13 } else if (xhr.readyState ==4){ 14 finished(xhr.response); 15 } 16 }; 17 xhr.send(null); 18 return xhr; 19 } 20 var client = createStreamingClient("streaming.php", function(data){ 21 alert("Received: " + data); 22 }, function(data){ 23 alert("Done!"); 24 });
這個例子能在大多數瀏覽器中正常運行(IE除外),但管理Comet鏈接很容易出錯,須要時間不短改進才能達到完美。