php 關於推送技術

PHPChina資訊:如果你在Google中搜索“AJAX Web 2.0”,你可以得到上億條搜索結果,但是你能從中發現有什麼技術能真正實現今天的Web 2.0所承諾的東西嗎?雖然Web 2.0至今還沒有一個統一的定義,不過它的核心一定是作爲社會化網絡平臺的互聯網,在這個平臺上具有相同愛好的羣體可以創建和分享信息。富互聯網應用 (RIA)體現了部分Web 2.0概念,它提供了一個更加高效的用戶界面,從而完善了Web 2.0平臺;而AJAX之於Web 2.0之處則在於,它提供了一個開發RIA應用的輕量級方法,即RIA應用可通過Web瀏覽器這個單一的界面來執行。

  如果研究一下像維基百科和博客等現有社會化網絡平臺的交互模式,你會發現它們都缺乏真實生活中人們交互的即時性的特點。因此可以把它們稱之爲準同步Web模式產品,當我們考慮Web 2.0規範的下一代平臺時,需要克服這個缺點。基於互聯網的聊天應用是最接近Web 2.0所需的即時交互特點的最簡單例子,但是對於AJAX技術來說,即便是以一個可擴展、輕量級、基於瀏覽器的機制來實現這些基本的功能,也是其能力範圍之外的事情。事實上,如果你仔細查看上面所說的上億條搜索結果,你會發現只有一些開源技術能夠解決通過標準瀏覽器機制異步推送內容給用戶的難題。後面我們將粗略介紹一下這些技術,不過讓我們先從最基本的東西開始介紹。

  基於Web的推送技術基本原理

  在將異步數據推送給瀏覽器方面,業內一直沒有一個標準的機制或名稱。在AJAX領域,該技術有不同的叫法,包括AJAX Push、Comet和Reverse Ajax,但是無論叫它什麼,這些不同的實現方法具有一個共同的特點。在瀏覽器中唯一的輕量級通信機制就是HTTP協議,但是它僅僅能夠幫助我們實現由瀏覽器發起的到服務器的通信的請求/響應的標準化。要想實現異步響應,有必要通過在服務器端保持一個開放的請求,當有更新的時候完成這個請求,實現對 HTTP協議的翻轉。通過下圖,我們可以瞭解標準的AJAX請求過程和通過翻轉機制來推送數據之間的不同。


  爲了支持異步推送,我們需要一直保持一個瀏覽器連接開放,來等待服務器端事件來觸發瀏覽器中的外觀變化。直覺告訴我們,這種實現方式存在問題,因爲我們在瀏覽器和服務器端都面臨着有關連接的問題。

  瀏覽器連接限制

  異步Web技術面臨的主要困難之一典型的瀏覽器“雙連接限制”問題。爲降低服務器負載,HTTP規範建議,用戶與每個服務器最多同時建立兩個連接,但是異步技術已經佔用了其中一個連接作爲通知通道使用。那麼考慮一下這種情況,多個瀏覽器窗口打開了同一個Web頁面,如果每一個窗口試圖建立它自己的連接,我們迅速會消耗完可用連接。爲了在這個限制下實現我們的目的,必須共享使用其中一個連接,但是出於安全原因,不同瀏覽器窗口的腳本環境是獨立分開的,這使得共同使用一個共享連接實現起來非常困難。另一個可以使用的技術是利用共享的HTTP cookie,通過它來實現與指定服務器的所有HTTP交互。該cookie被所有窗口所共享,通過JavaScript操作,還可用於跨窗口通信。

  但是,這個問題在portal頁面環境下再次被放大,因爲傳統的portal引擎都不支持必需的異步通信方式。爲了可以在多個portlet中使用推送技術,不僅僅需要共享瀏覽器連接,還需要一個專門的共享服務器連接來聚合異步響應。如果portlet是通過多個WARs進行部署的,情況可能會更復雜一些,共享機制必須在多個Web應用之間協同工作,而且將需要一些IPC機制來實現。

  在我們評價不同的推送機制的時候,理解它們如何解決共享連接的問題是非常重要的,因爲這個問題比較複雜,而且超出了一般應用程序開發者所能接觸的範圍。另外,瀏覽器廠商們可能會通過允許每窗口支持兩個連接,或者提供具有HTTP pipelining控制支持的XmlHttpRequest,從而允許不同的窗口共享一個專門的連接,來徹底降低連接共享的複雜性。

  應用服務器的可擴展性

  當我們從應用服務器角度來審視開放連接的問題時,我們發現了這個問題的多面性。我們都知道,現在的應用服務器可以高效率的處理大量的連接,但是在現有Servlet模式下,每一個連接需要執行一個線程。如果這些連接由於偶發性的服務器發起更新而變爲長期存活的話,服務器的可擴展性勢必受到線程池耗盡的嚴重威脅。

  雖然在servlet模型中關於異步通信的標準正在JSR315中被實現,但業界一直在通過完全不同的非標準化方法來解決這個問題。標準機制的缺失讓人非常失望,因爲任何可升級擴展的推送機制將需要與底層的服務器機制來緊密結合,需要實行專門的部署。好消息是,在開源應用服務器上已經出現許多不同的解決方案。

  Tomcat 6通過一個附加的Servlet接口——org.apache.catalina.CometProcessor,提供了異步請求處理(ARP)功能。 CometProcessor可以在當數據在連接上可讀的時候,讓Servlet接收事件,而不會通過阻塞讀來消耗一個線程。與不同的service() 方法相比,基於事件的機制讓開發者可以很好的對異步I/O處理進行控制。Tomcat 6還提供了一個CometFilter接口,當comet事件被處理的時候,才激活被調用的過濾器鏈。

  Glassfish V2/Grizzly通過類com.sun.enterprise.web.connector.grizzly.comet.CometEngine來提供ARP功能。應用程序可以通過一個CometHandler來註冊接受事件,而且和Tomcat 6一樣,當數據可用的時候處理讀事件,反之則執行阻塞讀操作。

  Jetty 6則在現有servlet API中提供了支持ARP的擴展機制。它的org.mortbay.util.ajax.Continuation類提供了suspend/resume 方法,來掛起請求操作,並在以後讓其在另一個不同的線程上異步恢復。當在servlet的Service()成員內調用suspend()時,將產生一個異常,並被Jetty服務器所捕獲,然後用於確認這個請求是否被恢復。恢復這個請求需要重新調用service()方法,然後它可以進行寫響應。延長機制的一個複雜之處是,service()方法必須被明確執行來支持觸發延伸。更好的做法是可以應用過濾機制的標準servlet,不過,過濾器同樣也必須處理觸發延伸的問題。

  ICEfaces異步HTTP服務器AHS算不上是一個應用服務器,但是它可以與任何應用服務器一起爲 ICEfaces應用提供ARP支持。和上面所提到機制不同之處是,沒有與AHS相關的編程API,它的功能是專門針對ICEfaces的。需要對AHS 進行配置來處理異步通訊通道,使用一個邊界線程池來對進行中的請求匹配更新。它可以被部署在羣環境中,包含一個servlet模式,可以被用來在 portal環境下處理AJAX推送。 

  開發模式

  在簡單理解了推送機制和它相應的複雜性之後,很多開發者選擇了對開發真正的推送風格應用敬而遠之。現在將我們的目光轉向那些可以幫助我們實現推送式應用程序開發的開源AJAX技術。

  Dojo/Cometd/Bayeux提供了一個以客戶端爲中心的編程模式和一個通用的可擴展到服務器的發佈/訂閱機制。我們可以爲專門的消息類定義一個專門的通道,這些通道的客戶端可存在於瀏覽器或服務器中。使用JavaScript應用邏輯來處理從服務器推送的消息,以及相應的更新用戶界面。從服務器角度來看,需要定義一個推送通道,然後服務器端應用邏輯通過該通道來發布事件。Cometd是一個非常靈活的機制,可同時支持在服務器端的Java和 Python實現。Cometd已經被集成到Tomcat 6、Grizzly和Jetty 6中。通過使用一個支持在窗口之間進行大數據傳輸的共享cookie機制,瀏覽器連接共享成爲可能。從本質上來說,Cometd方式帶來了一個鬆散耦合的分佈式系統,因此應用開發者需要解決一些相應的複雜問題,例如安全性和可維護性。

  DWR/Reverse AJAX則在遠程過程調用RPC基礎上提供了一個以客戶爲中心的編程模式。簡單來說,DWR通過JavaScript實現了從客戶端調用服務器端的 Java對象,而Reverse AJAX則是從服務器端的Java對象來調用JavaScript對象。對於一次推送交互,要求執行一個JavaScript來處理特定更新,服務器端的 Java邏輯必須合理的調用這個JavaScript。DWR servlet則通過HTTP連接來處理RPC呼叫集合,但是連接共享問題在JavaScript執行中沒有得到解決。DWR現已集成到Jetty 6中。

  ICEfaces/AJAX推送在JSF基礎上提供了一個以服務器爲中心的編程模式。ICEfaces對JSF進行了擴展之後,可以支持一個透明AJAX橋,它可以在JSF生命週期的基礎上實現更多針對瀏覽器的修改。一個簡單的擴展API允許應用程序邏輯在一些異步事件基礎上請求一個頁面刷新,瀏覽器客戶端的邏輯組合可以同時接收相同的更新。另外,它還提供了一個RenderHub功能來處理底層異步展現機制的同步和性能優化。 ICEfaces可以被配置成從Tomcat 6、Grizzly和Jetty中使用ARP機制,當然還有ICEfaces AHS。ICEfaces橋通過一個共享cookie機制來支持連接共享,當在servlet模式下配置AHS後,可以支持portal環境中的AJAX 推送。

  結束語

  在本篇文章中,我們把Web 2.0看作一個自然的即時社會化網絡平臺,而且也瞭解了使用輕量級Web技術來實現它所要求的推送功能的複雜性。儘管多數現有AJAX技術無法解決這一問題,不過一些開源技術已經出現,來幫助我們實現這個必需的功能。因此,有了這些開源技術,我們今天就能實現真正的Web 2.0。另外,隨着標準化的進一步落實,下一代瀏覽器實現也將最終降低實現這一功能的複雜性。如果推送式的Web應用和Web 2.0已進入你的視線,那麼投入到其中看看它能實現的強大應用吧。不過,需要提醒大家的是,你應該細心的檢查你現有的最佳開發模式和部署條件,進而設計一個方式,可以讓你將精力集中在應用程序開發上,而不是底層的推送功能開發上。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章