服務器推送數據之Comet

概念:Comet指的是一種更高級的ajax技術(稱爲‘服務器推送’)。ajax是一種從頁面向服務器請求數據的技術,而Comet則是

一種服務器向葉面推送數據的技術。Comet能夠讓信息近乎實時地傳遞到頁面,非常適合處理體育比賽的分數和股票報價。

實現Comet的方式有兩種:長輪詢

短輪詢(傳統輪詢):瀏覽器定時向服務器發送請求,看看有沒有更新的數據。如下圖:


長輪詢:長輪詢把短輪詢顛倒了一下。頁面發起一個到服務器的請求,然後服務器一直保持連接打開,直到有數據發送。發送完數據之後,瀏覽器關閉連接,隨即又發起一個到服務器的請求。這一過程在頁面打開期間一直持續不斷。如下圖:


無論是短輪詢還是長輪詢,瀏覽器都要在接收數據之前,先發起對服務器的連接。兩者的最大區別在於服務器如何發送數據。

短輪詢是服務器立即發送響應,無論數據是否有效,長輪詢是等待發送響應。

輪詢的優勢:所有的瀏覽器都支持輪詢,因爲使用XHR對象和setTimeout()就能實現。而你要做的就是決定什麼時候發送請求。


第二種實現Comet是http流。那麼問題來了,流和輪詢有什麼區別?

流在頁面的整個生命週期內只使用一個HTTP連接。具體來說,就是瀏覽器向服務器發送一個請求,而服務器保持連接打開,然後週期性地向瀏覽器發送數據。

那麼該怎麼來用呢?

在瀏覽器中,可以通過偵聽readystatechange事件和檢測readyState的值是否爲3,就可以利用XHR對象實現HTTP流。在Firefox,Safari,Opera和Chrome中,隨着不斷從服務器接收數據,readyState的值會週期性變爲3。當這個值爲3的時候,responseText屬性中就會保存接收到的所有數據。此時,就需要比較此前接收到的數據,決定從什麼位置開始取得最新的數據。代碼如下:

/*
		參數說明:
		url:要連接的服務器地址
		progerss:接收到數據時調用的杉樹
		finished:關閉連接時候調用的函數
	*/

	function createStreamingClient(url,progress,finished){
		var xhr = new XMLHttpRequest(),
			received = 0;
		xhr.open("get",url,true);
		xhr.onreadystatechange = function(){
			var result;

			if (xhr.readyState == 3) {
				//只取得最新數據並調整計數器
				result = xhr.responseText.substring(received);

				received += result.length;

				//調用progress回調函數
				progress(result);

			}else if (xhr.readyState == 4) {
				finished(xhr.responseText);
			}

		}
		xhr.send(null);

		return xhr;
	}

	var client = createStreamingClient("xxx.php",function(data){
		alert("received:"+data);
	},function(data){
		alert("Done!");
	});

只要readystatechange事件發生,而且readyState爲3,就對responseText進行分割以取得最新數據。這裏的received變量用於記錄已經處理了多少個字符,每次readyState值爲3的之後都遞增。然後,通過progress回調函數處理傳入的數據。當readyState的值爲4的時候,則執行finished回調函數,傳入響應返回的內容。

但是:Comet的連接容易出錯(IE),需要時間不斷改進才能達到完美。爲了簡化這一技術,又爲Comet創建了兩個新的接口,分別爲SSE和Web Sockets。

傳送門:服務器發送事件SSE和web sockets實時通信

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章