2010-07-08 66 views
4

我正在閱讀很多關於HTML5的內容,我特別喜歡網絡套接字,因爲它們促進了Web服務器和Web瀏覽器之間的雙向通信。http服務器如何處理html5 web套接字?

但我們繼續閱讀有關鉻,歌劇,火狐,Safari瀏覽器準備html5。哪個Web服務器準備好使用Web套接字功能?我的意思是,Web服務器能夠啓動今天的後續通信嗎? Google自己的Appengine怎麼樣?

如何編寫一個示例Web應用程序,以便在Java中利用此功能?

回答

10

Web服務器和瀏覽器之間的雙向通信並不新鮮。如果將新的答案發布到您正在閱讀的問題中,堆棧溢出會立即執行此操作。使用現有技術實現套接字式行爲有幾種不同的策略:

  • AJAX短輪詢:連接到服務器並詢問是否有任何新消息。如果不是,請立即斷開連接,並在短暫間隔後再次詢問。當您不想讓很多長時間運行的閒置連接對服務器開放時,這很有用,但這意味着您將只接收與輪詢間隔一樣快的新消息,並且會產生建立每次輪詢時新的HTTP連接。
  • AJAX長輪詢:連接到服務器並保持連接處於打開狀態,直到有新消息可用。這使您可以快速交付新消息和不太頻繁的HTTP連接,但會導致服務器上更長時間的空閒進程。
  • Iframe長輪詢:與上面相同,只能使用隱藏的iframe而不是XHR對象。當您想要進行跨站點長時間輪詢時,可用於繞過同源策略。插件:Flash的XMLSocket,Java小程序等可用於建立更接近真正的低級持久性套接字的瀏覽器。

HTML5套接字並沒有真正改變可用的底層策略。大多數情況下,他們只是將已經使用的策略形式化,並允許持續連接被明確識別,從而更加智能地處理。假設您想要在移動瀏覽器上執行基於Web的推送消息。通常的長輪詢,移動設備需要保持清醒狀態才能保持連接。使用WebSocket,當移動設備想要進入睡眠狀態時,它可以切斷與代理的連接,並且當代理接收到新數據時,它可以喚醒設備並返回消息。

服務器端是開放的。要實現短輪詢應用程序的服務器端,只需要某種按時間順序的消息隊列。當客戶端連接時,他們可以將新消息從隊列中移出,或者他們可以傳遞偏移量並讀取比偏移量更新的消息。

實現服務器端長輪詢是您的選擇開始縮小的地方。大多數HTTP服務器專爲短期請求而設計:連接,請求資源,然後斷開連接。如果有300人在10分鐘內訪問您的網站,並且每個人需要2秒鐘才能連接並下載HTTP資源,那麼您的服務器在任何給定時間將平均打開1個HTTP連接。通過一個長輪詢應用程序,您突然保持300倍的連接。

如果您正在運行您自己的專用服務器,您可能可以處理此問題,但在共享主機平臺上,您可能會遇到資源限制,App Engine也不例外。 App Engine被設計爲處理大量的低延遲請求,例如,短投票。您可以在App Engine上實施長時間輪詢,但這並不合適;運行時間超過30秒的請求將被終止,並且長時間運行的進程會佔用您的CPU配額。

App Engine的解決方案就是即將推出的Channel API。渠道API使用Google現有強大的XMPP基礎架構實現長輪詢。

Brett Bavar and Moishe Lettvin's Google I/O talk勾畫出使用模式如下:

App引擎應用創建一個遠程服務器上的一個信道,並返回它們通關到Web瀏覽器的信道ID。

class MainPage(webapp.RequestHandler): 

    def get(self): 
     id = channel.create_channel(key) 
     self.response.out.write(
      {'channel_id': id}) 

web瀏覽器將頻道ID到同一遠程服務器建立經由IFRAME長輪詢的連接:

<script src='/_ah/channel/jsapi'></script> 
<script> 
    var channelID = '{{ channel_id }}'; 
    var channel = 
    new goog.appengine.Channel(channelId); 
    var socket = channel.open(); 
    socket.onmessage = function(evt) { 
    alert(evt.data); 
    } 
</script> 

當一些有趣的情況發生時,應用程序引擎應用可以推一個消息給用戶的頻道以及瀏覽器的長輪詢請求將立即收到:

class OtherPage(webapp.RequestHandler): 

    def get(self): 
     # something happened 
     channel.send_message(key, 'bar') 
3

碼頭,例如,支持自7版本的功能:Jetty Websocket Server

谷歌的App Engine爲這個還計劃。他們甚至在Google I/O 2010上進行了這方面的演示,但尚未投入生產。請參閱ticket #377