轉載服務器推送技術

chyx413332087 11年前發布 | 4K 次閱讀 5.2.1版本發布

服務器推送技術

  最近幾天,一直在研究服務器推技術,在網上看了很多資料,也下載了很多小例子,總體來說,學到了一些東西,有些心得分享下:

  

  傳統模式的 Web 系統以客戶端發出請求、服務器端響應的方式工作。這種方式并不能滿足很多現實應用的需求,譬如:

    • 監控系統:后臺硬件熱插拔、LED、溫度、電壓發生變化;
    • 即時通信系統:其它用戶登錄、發送信息;
    • 即時報價系統:后臺數據庫內容發生變化;

  這些應用都需要服務器能實時地將更新的信息傳送到客戶端,而無須客戶端發出請求。“服務器推”技術在現實應用中有一些解決方案,本文將這些解決方案分為兩類:一類需要在瀏覽器端安裝插件,基于套接口傳送信息,或是使用 RMI、CORBA 進行遠程調用;而另一類則無須瀏覽器安裝任何插件、基于 HTTP 長連接。

  將“服務器推”應用在 Web 程序中,首先考慮的是如何在功能有限的瀏覽器端接收、處理信息:

    1. 客戶端如何接收、處理信息,是否需要使用套接口或是使用遠程調用。客戶端呈現給用戶的是 HTML 頁面還是 Java applet 或 Flash 窗口。如果使用套接口和遠程調用,怎么和 JavaScript 結合修改 HTML 的顯示。
    2. 客戶與服務器端通信的信息格式,采取怎樣的出錯處理機制。
    3. 客戶端是否需要支持不同類型的瀏覽器如 IE、Firefox,是否需要同時支持 Windows 和 Linux 平臺。

  

  而基于客戶端套接口的“服務器推”技術大體可以分為:

    傳統輪詢:在 Web 早期,這一點常使用 meta 刷新實現。這將自動指示瀏覽器在指定秒數之后重新裝載頁面,從而支持簡陋的輪詢( polling )。例如在 HTML 文件中加入 <META HTTP-RQUIV="Refresh" CONTENT=12> ,實際上就是 HTTP 頭標告知瀏覽器每 12 秒更新一次文檔。

          優點:不需要服務器端配置

          缺點:用戶體驗度差

             對服務器的壓力很大,帶寬流失嚴重

    ajax輪詢:Ajax 隔一段時間(通常使用 JavaScript 的 setTimeout 函數)就去服務器查詢是否有改變,從而進行增量式的更新。但是間隔多長時間去查詢成了問題,因為性能和即時性造成了嚴重的反比關系。間隔太短,連續不斷的請求會沖垮服務器,間隔太長,務器上的新數據就需要越多的時間才能到達客戶機。

          優點:不需要太多的服務器端配置

              降低了帶寬的負荷(因為返回的不是完整的頁面)

          缺點:對服務器的壓力并沒有減少

             實時性差,有一定的延遲

          應用:這種技術很常見,很多webmail應用程序就是通過這種技術在電子郵件到達時顯示電子郵件的。

    comet:Comet 方式通俗的說就是一種長連接機制 (long lived http) 。同樣是由 Browser 端主動發起請求,但是 Server 端以一種似乎非常慢的響應方式給出回答。這樣在這個期間內,服務器端可以使用同一個connection 把要更新的數據主動發送給 Browser 。因此請求可能等待較長的時間,期間沒有任何數據返回,但是一旦有了新的數據,它將立即被發送到客戶機。Comet 又有很多種實現方式,但是總的來說對 Server 端的負載都會有增加 . 雖然對于單位操作來說,每次只需要建議一次 connection, 但是由于 connection 是保持較長時間的 , 對于server 端的資源的占用要有所增加。

          優點:實時性好(消息延時小);性能好(能支持大量用戶)         

          缺點:長期占用連接,喪失了無狀態高并發的特點。

          應用:股票系統。實時通訊。

    flash xml socket:這種方案實現的基礎是:一、 Flash 提供了 XMLSocket 類。二、 JavaScript 和 Flash的緊密結合:在 JavaScript 可以直接調用 Flash 程序提供的接口。

          優點:實時性好(消息延時小);性能好(能支持大量用戶)         

          缺點:因為 XMLSocket 沒有 HTTP 隧道功能, XMLSocket 類不能自動穿過防火墻;

 

             因為是使用套接口,需要設置一個通信端口,防火墻、代理服務器也可能對非 HTTP 通道端口進行限制;

          應用:網絡聊天室,網絡互動游戲。

    java appet:在客戶端使用 Java Applet ,通過 java.net.Socket 或 java.net.DatagramSocket java.net.MulticastSocket 建立與服務器端的套接口連接,從而實現  服務器推送  

          缺點:需要安裝java虛擬機

    html5:此技術是一個在我認為中較好的技術了,內置了websocket,可以參考這里

    servlet3.0:作為 Java EE 6 體系中重要成員的 JSR 315 規范,將 Servlet API 最新的版本從 2.5 提升到了 3.0,這是近 10 年來 Servlet 版本號最大的一次升級,此次升級中引入了若干項令開發人員興奮的特性,詳解請看這里

  而我所想探討的方向是comet:

    comet的介紹:Comet 有時也稱反向 Ajax 或服務器端推技術( server-side push )。其思想很簡單:將數據直接從服務器推到瀏覽器,而不必等到瀏覽器請求數據。聽起來簡單,但是如果熟悉 Web 應用程序,尤其是 HTTP 協議,那么您就會知道,這絕不簡單。實現 Comet 風格的 Web 應用程序,同時保證在瀏覽器和服務器上的可伸縮性,這只是在最近幾年才成為可能。目前一些主流網站都有類似的原理,例如: webQQ 、開心網、校內等等,它們中消息動態都是采用類似的技術,只是具體實現方式不一樣。

           COMET 的精髓就在于用服務器與 javascript 來維持瀏覽器的長連接,同時完成服務器端事件的瀏覽器端響應。這樣的事件廣播機制是跨網絡的,同時也是實時的。

           采用了 Comet 技術的服務器在客戶機做出一個請求后,和客戶機建立一個永久的連接,然后服務器會根據客戶機的請求不斷把數據包推向客戶,這個推的過程是不間斷的。由服務器推向客戶機的數據在客戶機的瀏覽器上會不斷產生新的內容,而且不會產生 Client pull 那樣的 HTML 文檔頭,從而大大減少了延遲的時間,向(服務器響應 -- 客戶機請求)同步邁進了一步。

            服務器推送通常效率要比客戶端拖曳效率高,因為它不必為后續數據建立新的連接。由于始終保持連接,即使沒有數據傳輸時也是這樣,因此服務器必須愿意分配這些 TCP/IP 端口,對于 TCP/IP 端口數有限的服務器這將是一個嚴重的問題。

            客戶端拖曳效率低,因為這必須每次為傳送數據建立新的連接。但是它不必始終保持連接。在實際情況中,建立 HTTP 連接通常需要花費相當多的時間,多達一秒甚至更多。因此從性能上考慮,服務器推送對于最終用戶更有吸引力,特別是對于需要經常更新信息的情況下。

            服務器推送相對客戶端拖曳的另一點優勢是,服務器推送相對比較容易控制。例如,服務器每一次推送時都保持一個連接,但它又隨時可以關閉其中的任何連接,而不需要在服務器上設置特殊的算法。而客戶端拖曳在同樣的情況下要麻煩許多,它每次要與服務器建立連接,服務器為了處理將客戶端拖曳請求與特定的最終用戶匹配等情況,需要使用相當麻煩的算法。

           如上所述,在服務器推送中,多個響應中連接始終保持,使服務器可在任何時間發送更多的數據。一個明顯的好處是服務器完全能夠控制更新數據的時間和頻率。另外,這種方法效率高,因為始終保持連接。缺點是保持連接狀態會浪費服務器端的資源。服務器推送還比較容易中斷。

    如果談到comet的實現,我想應該有死循環法,改寫web服務器,和使用框架

    下面是我所參考的一些資料

      其實實現comet,已經有很多開源的框架了,詳情請參考這里

      像apahe的jetty項目內部就有comet的例子,想看效果的朋友可以去下載看看,只是jetty主要是介于Continuations特性的

      在comet的開源框架中,我選擇了pushelt,現在的版本好像是2.0.4,主要是使用了觀察者模型。瀏覽器端提供了基于 AJAX 和 iframe 的 JavaScript 庫,服務器端使用 Java Servlet。

      其實dwr框架也可以實現服務器推送的技術,在此不具體講解了;

 本文由用戶 chyx413332087 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!