程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 淺入淺出“服務器推送”之一:Comet簡介,淺出comet

淺入淺出“服務器推送”之一:Comet簡介,淺出comet

編輯:JAVA綜合教程

淺入淺出“服務器推送”之一:Comet簡介,淺出comet


最近有個項目,其中有項需求要從服務器端主動向客戶端推送數據,本以為很簡單,但在實際做的過程中發現很棘手,並沒有想象中的簡單。從網上搜索學習,發現主流講的還是Ajax的長輪詢技術或者流技術,websocket還多多少少存在些弊端。為了便於記憶,也為了對跟我一樣的菜鳥提供些幫助和參考,把學習過程中學習拜讀的文章和體會記錄下來,以備以後查驗和溫習。大多數內容屬於網絡整理,也有一部分屬於實踐的體會,希望對大家有所幫助。

隨著AJAX技術的興起,讓廣大開發人員又一次看到了使用浏覽器來替代桌面應用的機會,並且這次機會非常大。AJAX將整個頁面的刷新變成頁面局部的刷新,並且數據的傳送是以異步方式進行,這使得網絡延遲帶來的視覺差異將會消失。AJAX還利用DHTML和豐富的JavasSript語言來模擬桌面系統的各種事件和響應過程,以及平滑滾動和拖拽的效果。還不止這些,更有一些IT巨頭(Google、Sun、Oracle等)提供了非常豐富的AJAX開發工具,使得開發和調試AJAX應用變得簡單高效,並且開發的AJAX應用還可以跨越各種浏覽器和操作系統。在這種情況下基於AJAX的Web應用迅速湧起,吞噬著原有桌面系統的份額。聊天工具、郵件閱讀器、博客編輯器,甚至是Office辦公軟件和文字處理軟件在浏覽器中都有著美麗的外觀和幾乎可以與桌面系統媲美的交互界面。Google更是提出“有了浏覽器和Google,就不需要微軟”的口號和策略。在Ajax的世界中,除了傳統的CAD設計軟件和大型游戲軟件等因為對系統硬件的苛刻需求,還離不開桌面系統以外,似乎其他所有的應用都可以變成Web應用了。

但是,在浏覽器中的AJAX應用中存在一個致命的缺陷無法滿足傳統桌面系統的需求。那就是“服務器發起的消息傳遞(Server-Initiated Message Delivery)”。在很多的應用當中,服務器軟件需要向客戶端主動發送消息或信息。因為服務器掌握著系統的主要資源,能夠最先獲得系統的狀態變化和事件的發生。當這些變化發生的時候,服務器需要主動地向客戶端實時地發送消息。例如股票的變化。在傳統的桌面系統中,這種需求沒有任何問題,因為客戶端和服務器之間通常存在著持久的連接,這個連接可以雙向傳遞各種數據。而基於HTTP協議的Web應用卻不行。在Web世界中,服務器永遠是被動地發送數據,前提是客戶端必須先發送請求。浏覽器其實並不知道服務器的信息什麼時候會有改變,為了模擬實時的交流,或者不想錯過某些信息,只能通過輪詢(Polling)技術不斷刷新頁面來獲得最新的數據。這種方式不但浪費服務器的資源,最重要的是每次建立(或關閉)新的HTTP連接都有一定的延遲,這種延遲使得頻繁信息傳遞的應用無法忍受。於是就產生了“服務器推送技術”。

“服務器推”是一種很早就存在的技術,以前在實現上主要是通過客戶端的套接口,或是服務器端的遠程調用。因為浏覽器技術的發展比較緩慢,沒有為“服務器推”的實現提供很好的支持,在純浏覽器的應用中很難有一個完善的方案去實現“服務器推”並用於商業程序。最近幾年,因為 AJAX 技術的普及,以及把 IFrame 嵌在“htmlfile“的 ActiveX 組件中可以解決 IE 的加載顯示問題,一些受歡迎的應用如 meebo,gmail+gtalk 在實現中使用了這些新技術;同時“服務器推”在現實應用中確實存在很多需求。因為這些原因,基於純浏覽器的“服務器推”技術開始受到較多關注,Alex Russell(Dojo Toolkit 的項目 Lead)稱這種基於 HTTP長連接、無須在浏覽器端安裝插件的“服務器推”技術為“Comet”。目前已經出現了一些成熟的 Comet 應用以及各種開源框架;一些 Web 服務器如 Jetty 也在為支持大量並發的長連接進行了很多改進。關於 Comet 技術最新的發展狀況請參考關於 Comet 的 wiki。

下面介紹兩種 Comet 應用的實現模型。

一、基於 AJAX 的長輪詢(long-polling)方式

AJAX 的出現使得 JavaScript 可以調用 XMLHttpRequest 對象發出 HTTP 請求,JavaScript 響應處理函數根據服務器返回的信息對 HTML 頁面的顯示進行更新。使用 AJAX 實現“服務器推”與傳統的 AJAX 應用不同之處在於:

服務器端會阻塞請求直到有數據傳遞或超時才返回。

客戶端JavaScript 響應處理函數會在處理完服務器返回的信息後,再次發出請求,重新建立連接。

當客戶端處理接收的數據、重新建立連接時,服務器端可能有新的數據到達;這些信息會被服務器端保存直到客戶端重新建立連接,客戶端會一次把當前服務器端所有的信息取回。

一些應用及示例如 “Meebo”, “Pushlet Chat” 都采用了這種長輪詢的方式。相對於“輪詢”(poll),這種長輪詢方式也可以稱為“拉”(pull)。因為這種方案基於 AJAX,具有以下一些優點:請求異步發出;無須安裝插件;IE、Mozilla FireFox 都支持 AJAX。

在這種長輪詢方式下,客戶端是在 XMLHttpRequest 的 readystate 為 4(即數據傳輸結束)時調用回調函數,進行信息處理。當 readystate 為 4 時,數據傳輸結束,連接已經關閉。Mozilla Firefox 提供了對 Streaming AJAX 的支持, 即 readystate 為 3 時(數據仍在傳輸中),客戶端可以讀取數據,從而無須關閉連接,就能讀取處理服務器端返回的信息。IE 在 readystate 為 3 時,不能讀取服務器返回的數據,目前 IE 不支持基於 Streaming AJAX。

二、基於 Iframe 及 htmlfile 的流(streaming)方式

iframe 是很早就存在的一種 HTML 標記, 通過在 HTML 頁面裡嵌入一個隱蔵幀,然後將這個隱蔵幀的 SRC 屬性設為對一個長連接的請求,服務器端就能源源不斷地往客戶端輸入數據。

上節提到的 AJAX 方案是在 JavaScript 裡處理 XMLHttpRequest 從服務器取回的數據,然後 Javascript 可以很方便的去控制 HTML 頁面的顯示。同樣的思路用在 iframe 方案的客戶端,iframe 服務器端並不返回直接顯示在頁面的數據,而是返回對客戶端 Javascript 函數的調用,如“<script type="text/javascript">js_func(“data from server ”)</script>”。服務器端將返回的數據作為客戶端JavaScript 函數的參數傳遞;客戶端浏覽器的 Javascript 引擎在收到服務器返回的 JavaScript 調用時就會去執行代碼。

這種方式每次數據傳送不會關閉連接,連接只會在通信出現錯誤時,或是連接重建時關閉(一些防火牆常被設置為丟棄過長的連接, 服務器端可以設置一個超時時間, 超時後通知客戶端重新建立連接,並關閉原來的連接)。

使用 iframe 請求一個長連接有一個很明顯的不足之處:IE、Morzilla Firefox 下端的進度欄都會顯示加載沒有完成,而且 IE 上方的圖標會不停的轉動,表示加載正在進行。Google 的天才們使用一個稱為“htmlfile”的 ActiveX 解決了在 IE 中的加載顯示問題,並將這種方法用到了 gmail+gtalk 產品中。Alex Russell 在 “What else is burried down in the depth's of Google's amazing JavaScript?”文章中介紹了這種方法。Zeitoun 網站提供的 comet-iframe.tar.gz,封裝了一個基於 iframe 和 htmlfile 的 JavaScript comet 對象,支持 IE、Mozilla Firefox 浏覽器,可以作為參考

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved