Servlet 3.0筆記之異步請求重新梳理Comet的幾種形式
本來只是想梳理以下Servlet 3.0異步請求,不曾想涉及到Comet(維基百科上面對comet有具體的定義和介紹),篇章多了起來,對以往所學習和心得,重新梳理一下。
Comet的實現主要流(streaming) 形式和長輪詢(long polling)兩種形式。流和長輪詢區別主要在于,在一次連接中,服務器端推送多次的數據為流,只推送一次為長輪詢。
流推送(Comet Streaming)
Comet流推送目前一般采用:
- 隱藏IFrame(Hidden iframe)
服務器端一般會輸出一段javascript腳本<script>comet.showMsg(“這是新的消息”)</script>
好處在于各個瀏覽器都支持iframe,目前在IE、Firefox下面效果最好,頁面不再顯示正在加載中的討厭的提示(見Servlet 3.0筆記之異步請求Comet推送iFrame示范) - XMLHttpRequest
很可憐,目前支持情況最好的是火狐瀏覽器、IE8以及Safari
參考文章:
Servlet 3.0筆記之異步請求Comet推送XMLHttpRequest示范
Servlet 3.0筆記之異步請求Comet流推送(Streaming)實現小結。
長輪詢(Ajax with long polling)
客戶端會與服務器建立一個持久的連接,直到服務器端有數據發送過來(超時也會發送數據),雙方斷開連接,客戶端處理完推送的數據,會再次發起一個持久的連接,循環往復。其實現形式:
- XHR方式長輪詢(XMLHttpRequest long polling)
服務器端可以返回原始的數據,也可以返回格式化的JSON、XML、JAVASCRIPT信息,相比iframe形式流推送,更自由一些。使用形式和傳統意義上的AJAX GET方式大致一樣,只不過下一次的輪詢需要等到有數據返回處理完方可。
默認不支持跨域,實踐中會打折扣。 - JAVASCRIPT標簽輪詢(Script tag long polling)
可能翻譯不太準確,主要使用類似于如下形式:<script src='js/yourCometProvider.js' type='text/javascript'></script>
使用跨域的JS腳本,可能會有安全方面隱患,或許這個間接風險是可控的。
也可以使用JSONP用以規避這個風險。
進階閱讀:Comet (long polling) for all browsers using ScriptCommunicator
代碼寫的很巧妙,也很簡短,思路不錯,推薦一看。
參考文章:
Servlet 3.0筆記之異步請求Comet推送長輪詢(long polling)篇
Servlet 3.0筆記之異步請求Comet推送長輪詢(long polling)篇補遺
Comet瀏覽器支持匯總
大致總結一下各個瀏覽器對Comet支持大致情況,可能不太科學,僅以自己實踐中感知為準。table{border:1px solid #888888;border-collapse:collapse;font-family:Arial,Helvetica,sans-serif;margin-top:10px;width:100%;}table th {background-color:#CCCCCC;border:1px solid #888888;padding:5px 15px 5px 5px;text-align:left;vertical-align:baseline;}table td {background-color:#EFEFEF;border:1px solid #AAAAAA;padding:5px 15px 5px 5px;vertical-align:text-top;}瀏覽器 | 流(streaming) | 長輪詢(long polling) |
---|---|---|
IE(6-8) | htmlfile + iframe 支持流形式; IE8的XDomainRequest支持HTTP Streaming | 支持腳本加載事件;頁面表現完美 |
Firefox(3.5) | 支持XMLHttpRequest Streaming 和隱藏的IFrame組件 | 支持腳本文件async屬性;頁面表現完美 |
Chrome(>9.0) | 不支持XMLHttpRequest Streaming;使用IFrame會一直出現正在加載中圖標 | 支持腳本文件async屬性;頁面表現完美 |
Safari(5) | 瀏覽器支持XMLHttpRequest Streaming | 支持腳本文件的async屬性;頁面表現完美 |
Opera(>9.0) | 不支持XMLHttpRequest Streaming,使用IFrame的話會一樣會出現正在加載中的標志 | 本機測試腳本文件長輪詢時間若長于20秒,則會出現連接中斷情況;會出現正在加載中的標志 |
Servlet 3.0 支持
長輪詢或流推送,相對于Servlet 3.0 異步請求,相差不大,都需要定義一個連接超時時間,但后者可以向客戶端推送多次,前者推送一次之后需要立刻斷開了與客戶端的連接;在超時事件發生后,都可以通知客戶端超時已發生。另外在高并發環境下可能需要做多層次的消息路由服務以降低單機的處理極限。實踐中使用Comet流推送,也需要在一定的時間后再次重連,或許可以稱之為流輪詢(streaming poll),只是人們沒有提起而已。
發布訂閱模型(Publish/Subscribe)
Comet為發布/訂閱模型在前端應用的一種變形??梢院苤庇^的將服務器端視為內容發布者,瀏覽器端為訂閱者。相對于谷歌的pubsubhubbub協議,區別在于Comet使用HTTP 1.1 長連接協議,客戶端為瀏覽器,沒有公開的可回調的客戶端地址。而pubsubhubbub則要求訂閱者有一個可以回調的URL地址(這個URL對于發布者服務器是直達的),一旦有新的可用數據,可以推送到客戶端,客戶端某個URL監聽就是。雙方在用途、使用環境上不相同,需要區別對待。話說觀察者模式在實際應用中十分廣泛,變體也很多。
參考資料:
posted on 2011-02-27 17:17 nieyong 閱讀(2731) 評論(0) 編輯 收藏 所屬分類: Servlet3