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來管理就能夠了。
這個是個人思路,我尚未實踐,若是你須要的話,能夠本身去試一下javascript