DWR推技術在開發中需要注意的ScriptSession問題

1 關於ScriptSession
ScriptSession不會與HttpSession同時創建
當我們訪問一個頁面的時候,如果是第一次訪問,就會創建一個新的HttpSession,之後再訪問的時候,就會保持當前的Session,即使是刷新,也能保持當前的HttpSession。
但是,ScriptSession不同,第一次訪問,會創建一個ScriptSession,但是,如果你刷新,就會創建一個新的ScriptSession.


2 如何得到ScriptSession
在DWR中,我們可以通過WebContextFactory.get()來取得一個WebContext對象,進而通過WebContext的getScriptSession()取得ScriptSession對象。
但是要注意,在我們自定義的Servlet中,我們也可以通過WebContextFactory.get()來取得一個WebContext,但是這種方法卻不能取得ScriptSession對象。因爲,此WebContext對象其實不是通過DWR的上下文環境得到的,所以,就根本沒有創建ScriptSession對象。
假設這種方式也能得到ScriptSession的話,那麼我們實現“推”也就可以不侷限在DWR的上下文環境中了,那麼其靈活性就會大很多了。

所以,這就是我們不能在Servlet中實現推的原因。

3 關於刷新就創建一個新的ScriptSession問題
 在我們需要推送的頁面中,如果你刷新以下,那麼就提交一個Http的request,此時,如果是第一次,那麼就會創建一個httpSession對象,同時,請求由DwrServlet來處理後,就會創建一個ScriptSession.這個ScriptSession會和你的request請求的URI綁定放在一個由ScriptSessionManager維護的Map裏面(這裏面其實是一個URI對應的Set,在Set裏面放置的是URI綁定的所有ScriptSession)。
當你刷新的時候,同樣的一個HttpSession,卻會創建一個新的ScriptSession,然後綁定到對應的URI上。

4 向所有的頁面訪問者推送
當我們想向所有的頁面訪問者推送的時候,我們只需要,取得所有的頁面訪問者,就可以“推”了。
如何取得所有的頁面訪問者?可以通過
//        Collection pages = webContext.getScriptSessionsByPage("/SynMap/map/map.jsp");
來取得/SynMap/map/map.jsp的所有訪問的ScriptSession
如何推送,
Util util = new Util(pages);
util.addFunctionCall("syningMap",new Double(x),new Double(y),new Integer(zoom));
通過此方法,就可以實現調用客戶端的javascript函數,實現對客戶端的操作。

5 在上面的推送中產生的問題
上面的方法已經可以實現向所有的訪問者推送。但是問題是,在客戶端,如果用戶刷新一次或多次,那麼,Collection裏面可能就保存了很多的無用的ScriptSession,所以不僅僅會影響性能問題,更重要的是,可能就不能實現你想要的功能。

比如,你想取得當前再現的有效用戶,那麼你就需要知道那些ScriptSession是有效的。

6 如何管理有效的ScriptSession

由於上面的問題,我們就需要自己管理ScriptSession.其實,有效地HttpSession,就是那個和當前的HttpSession匹配的ScriptSession.
所以,我們就可以自己維護一個Map,在這個Map裏面,我們定義key就是HttpSession的Id,其值就是ScriptSession對象。
在每一次頁面載入的時候,都去註冊此ScriptSession,那麼就會把新的ScriptSession綁定到httpSession上面了。
// session and scriptSession map
Map sm = g.getSessions();
// hs is HttpSession
// ss is ScriptSession object
sm.put(hs.getId(), ss);

7 如何實現有效推送
通過上面的Map取得所有的有效ScriptSession集合
Collection pages = g.getSessions().values();
然後再推送,就可以了。

8 上面問題的新的解決方案
上面的技術問題和解決方案都是在DWR2.0的環境下遇到的。
昨天看了一下,即將正式發佈的DWR3.0的文檔,裏面對AJAX Reverse技術增加了不少功能。
其中新加了一個象HttpSessionListener的東西,叫ScriptSessionListener
所以,我想,可以通過這個Listener實現上面的功能,也就是說,在監聽到一個ScriptSession創建的時候,我們就直接判斷,並把此ScriptSession綁定到httpSession上,就可以了。同樣用上面的那個map來管理就可以了。
這個是我的思路,我還沒有實踐,如果你需要的話,可以自己去試一下。
新版本的DWR開發實現推技術會更加方便,期待吧!!

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