淺談 Polling, Comet, Websocket

淺談 Polling, Comet, Websocket

前言 #

現在需要做即時回應與更新的網站已是愈來愈多,大至 Facebook、Twitter,小至即時聊天室的實作等等,在以前使用者只能靠著重新載入網頁才能獲得最新的資訊,但是這樣不但很浪費時間,也會佔用很多不必要的網路資源,並不是一個好的方式。

現在要實作這樣的功能,當然不能不知道一些網路推播技術 Internet Push technology——對這個名詞很陌生嗎?讓我們來看看維基百科的說明:

推播技術,是一種基於 Internet 通訊方式的伺服器推播,其中要求通訊的請求是由發布者或中央伺服器發起。與 pull/get 形成對比,資訊傳輸的相應一般由接收者或用戶端發起。
推動服務通常是基於提前的資訊預設定上。也就是所謂的 publish/subscribe 模型,客戶通過訂閱由伺服器提供各種資訊的頻道,不論何時都可以在其中一個頻道得到新的內容,同樣伺服器通過推播把資訊傳遞給相應的用戶端。

Polling 輪詢 #

先來談談傳統的 Polling 輪詢技術,基本上原理很簡單,就是每隔一段固定時間就自動送出 Request 給伺服器,去跟伺服器要資料就對了!

(function poll(){
setTimeout(function(){
$.ajax({ url: "server", success: function(data){
// Do something to update your view

// Setup the next poll recursively
poll();
}, dataType: "json"});
}, 30000);
})();

它有以下幾個特點:

但也有致命的缺點:

這個做法是最老舊的方式,如果你已經事先知道伺服器上資料更新的頻率或時間,那麼也許用這樣的方式去做資料的同步更新。
但現在許多的網頁應用程式上並不是這樣,你通常不會知道伺服器上的資料何時會更新,在伺服器沒有新資料時,瀏覽器如果也送出 Request,就會造成浪費網路資源的狀況。而 Comet 的出現解決了 Polling 這樣的弊端。

Comet #

Comet 在英文中也就是彗星的意思,顧名思義發出的 Request 會像彗星的尾巴般,將 Request 拉長,讓伺服器可以想傳資料就傳,不需要等客戶端先送請求伺服器再回傳,讓伺服器實時地將更新的資訊傳送到用戶端

Comet 原先的精神是發出 Request 後不馬上結束,但這種做法卻引申出另一個問題那就是他會把傳統的 Web 伺服器(例如 Apache)的連線給佔住。所以 Comet 的技術得配合 Non-Blocking IO 的 Web 伺服器才能非同步處理。

後來發展出改良式的 Comet,伺服器會發一個長時間等待的 Request、當伺服器有資料 Response 時立刻斷掉、接著再發一個新的 Request。

這種改良式的 Comet 主要有兩種實作方式:

瞭解 Comet 的原理後,我們其實可以發現 Comet 的最大瓶頸在於控制連線生命週期上需要反覆發出請求,而導致效能會較差,然而 WebSocket 的出現卻解決了這個問題,讓效能不會卡在連線生命週期,增強了資料傳輸的效率。

WebSocket #

WebSocket 是定義在 HTML5 標準中的一個新的網頁傳輸方式,可在一條連線上提供全雙工、雙向的資料傳輸。在這樣的標準下你可以很容易實作一個兼具可擴充性與即時性的網頁應用程式。

同時因為 WebSocket 提供瀏覽器一個 原生(native) 的 socket,所以直接解決了 Comet 架構很容易出錯的問題,而在整個架構的複雜度上也會比傳統的做法簡單很多。

簡單來說就是利用了新的協定建立了雙向的通道:當通道建立起來之後,Browser 可以隨時丟訊息給 Server、Server 可以隨時丟訊息給瀏覽器。唯一的小缺點就是可能有一些瀏覽器相容性的問題必須要解決,IE10 以前的版本並不支援。

在使用前,需要建立一個 WebSocket 物件。

  var ws = new WebSocket('ws://server');
ws.onmessage = function(message) {
alert(message.data);
ws.close()
};
ws.send('Hello WebSocket.');

WebSocket 可以選擇 ws 或是 wss 通訊協定。

操作上十分單純,以 send() 送出訊息,而以 onmessage 事件接收訊息。
呼叫 close() 即可結束連線。這中間無法改變通訊的 url。

比起前端的使用操作,在後端、伺服器上實作 WebSocket Protocol 倒是複雜多了。這部分就不多贅述。

總而言之,透過 WebSocket 建立永久連線,這種開放式連線可以讓客戶端和伺服器端之間隨時雙向交換資料,因此可降低延遲時間,改善資源使用效率,必定會是未來的潮流和趨勢。

分享文章