pushlet

pushlet是comet的一種實現,而且是開源,其聲 稱能支持目前的web 服務器,於是就對其提供的服務器端以及客戶端代碼進行了一番研究,心得如下: 在要使用push的頁面中通過執行p_embed()向當前頁面添加用來與server通訊的iframe 。後臺通訊的頁面叫js_pushlet_js.html頁面,在這個頁面中包含兩個frame:一個負責發送請求,也就是controlFrame,一 個負責接受請求,即listenFrame。

clientAdapter的作用:clientAdapter實際上是對response的一個封裝,根據向 response中write不同的數據,可以分爲不同的clientAdapter實現,比如BroswerAdapter就是爲了處理瀏覽器發送的請 求。

在每次打開頁面之後都要建立與後臺的聯繫,這個一般都是通過js函數join來實現的,join會調用 js_push_client.js中的通用函數(p_join_listen)來做兩件事: 第一個就是調用p_join,給用來通訊的iframe賦location.href值,讓它去發送請求,接收請求的是 nl.justobjects.pushlet.servlet.Pushlet這個servlet。

並通過p_event=join告訴後臺開始建立連接。在發送完請求之後,後臺會response回來一段新的js 代碼,處理方法是:String nl.justobjects.pushlet.core.BrowserAdapter.event2JavaScript(Event event) throws IOException,裏面的返回結果是:" ",後臺在處理完join事件之後將結束response。

push()這個函數在 js_pushlet_net.html這個頁面中,不過它還會調用js_pushlet_client.js庫中的_push()函數,push函數會 根據server傳回的參數(這些參數都是一些後臺要調用的事件參數),最終我們會根據返回的參數執行相應的回調函數,這些回調函數在事件的應用html 應用頁面中實現,比如ping.html頁面,回調函數有:onData等。

第二件事就是調用p_listen再次向後臺發送請求(由負責與後臺通訊的iframe中另外一個子frame來處 理),不過此時需要後臺執行的是listen事件,listen跟其他事件不同在於它先找到當前 session對應的訂閱者(subscriber),然後調用subscriber的fetchEvent()方法,從訂閱者的event queue中取出所有的event對象 ?在js_pushlet_client.js中有一個全局變量:pushletNet這個指的就是用來與後臺通信的那個iframe對象,還有一個全局 的變量是pushletURI,這個指的是要請求的servlet url。

後臺Event的處理機制:對Event的處理放在EventSource中,EventSource分兩種:pull和push,目前主要是pull方 式(似乎有些與pushlet矛盾),EventSource有多個實現,這些實現會在source.properties中註冊,然後由 EventSourceManager進行管理,EventSource同時會實現Runnable接口,即會用到多線程,在Servlet初始化的時候 通過啓動EventSourceManager來啓動多個EventSource線程。

由於pushlet採用的是發佈/訂閱模式,在將Event發送給客戶端前,首先要找到所有的客戶端對象,這個通過 一個pushlet自己定義的session(每一個連接到服務器的客戶端會在服務器上註冊一個 session來保存客戶端信息,在每次發送請求的時候會帶有一個sessionid來加以識別)來處理,然後從所有連接的客戶端找到訂閱了該event 的訂閱者,這個是在Dispatcher的multicast()方法中進行的,在訂閱者中有一個event queue對象,廣播的event對象將保存到該queue中。

從queue中抓取event的過程則交給controllor完成。 前臺需要連續發送請求?不需要,如果需要拼命的發送請求,就不叫comet了,前臺只需要發送兩個請求,一個是請求連接的join請求事件,一個是對後臺 進行監聽的listen事件,如果後臺對應的數據發生了變化,則這個變化會反應到訂閱者的event隊列中,監聽事件請求就是不斷的讀取訂閱者的 event隊列即可。response需要請求執行完成之後關閉嗎?在第一個join事件請求是需要關閉的,listen事件請求則不需要。

如果客戶端連接關閉了,後臺如何知曉?在向response中write數據的時候拋出異常,後臺就會知道可能是客戶端已經關閉,這樣該輸出將結束 ?pushlet中如何與ajax結合使用?如果使用ajax的話,就是將iframe換成了xmlhttp,後臺無變化,就是這麼簡單!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章