DWR“推”

 

网上找到不少相关例子,不过大部分是dwr2的例子,效果一般,研究了一下dwr3.0相关内容,做了个DEMO,实现了向一个或多个精确目标推送内容。

重点在于向ScriptSessionManager中加入ScriptSessionListener监听ScriptSession的创建和销毁。

ScriptSessionListener中有2个需要实现的方法sessionCreated和sessionDestroyed,分别对应ScriptSession的创建和销毁,可以在方法中加入需要的内容。

 

我是在web.xml中配置了一个启动自动运行的servlet,用来添加监听。

InitScriptSession.java

  1. import javax.servlet.GenericServlet;  
  2. import javax.servlet.ServletContext;  
  3. import javax.servlet.ServletRequest;  
  4. import javax.servlet.ServletResponse;  
  5. import javax.servlet.http.HttpSession;  
  6.   
  7. import org.directwebremoting.Container;  
  8. import org.directwebremoting.ScriptSession;  
  9. import org.directwebremoting.ServerContextFactory;  
  10. import org.directwebremoting.WebContextFactory;  
  11. import org.directwebremoting.event.ScriptSessionEvent;  
  12. import org.directwebremoting.event.ScriptSessionListener;  
  13. import org.directwebremoting.extend.ScriptSessionManager;  
  14.   
  15. public class InitScriptSession extends GenericServlet {  
  16.   
  17.     ServletContext application;  
  18.   
  19.     public void init() {  
  20.         Container container = ServerContextFactory.get().getContainer();  
  21.         ScriptSessionManager manager = container  
  22.                 .getBean(ScriptSessionManager.class);  
  23.         ScriptSessionListener listener = new ScriptSessionListener() {  
  24.             public void sessionCreated(ScriptSessionEvent ev) {  
  25.                 HttpSession session = WebContextFactory.get().getSession();  
  26.                 ScriptSession scriptSession = ev.getSession();  
  27.                 String userId = session.getAttribute("userId").toString();  
  28.                 scriptSession.setAttribute("userId", userId);  
  29.                 System.err.println("创建---"+scriptSession.getId()+"------- put userId into scriptSession as "  
  30.                         + userId);  
  31.             }  
  32.   
  33.             public void sessionDestroyed(ScriptSessionEvent ev) {  
  34.                 System.out.println("销毁-----"+ev.getSession().getId());  
  35.             }  
  36.         };  
  37.         manager.addScriptSessionListener(listener);  
  38.     }  
  39.   
  40.     public void service(ServletRequest req, ServletResponse res) {  
  41.         init();  
  42.     }  
  43. }  

 

在sessionCreated方法中把当前登陆人ID标识放入ScriptSession中,后面的推送过程中通过该标识判断推送目标。

 

推送方法:

  1. /** 
  2.  * 推给指定用户 
  3.  * @param userid 
  4.  * @param request 
  5.  * @return 
  6.  */  
  7. private void send(final String receiverid, final String msg) {  
  8.     Browser.withAllSessionsFiltered(new ScriptSessionFilter() {  
  9.         public boolean match(ScriptSession session) {  
  10.             if (session.getAttribute("userId") == null)  
  11.                 return false;  
  12.             else  
  13.                 return (session.getAttribute("userId")).equals(receiverid);  
  14.             }  
  15.         }, new Runnable() {  
  16.             public void run() {  
  17.                 Collection<ScriptSession> colls = Browser.getTargetSessions();  
  18.                 for (ScriptSession scriptSession : colls) {  
  19.                     scriptSession.addScript(initFunctionCall(  
  20.                             "dwr.util.setValue""info", msg));  
  21.                 }  
  22.             }  
  23.         });  
  24.     }  

 

其他方法与网上查到的基本大同小异,有需要的朋友可以去网上down下来研究下。

 

重点关于解决页面每刷新一次会多创建一个新的ScriptSession的解决方法

由于ScriptSession的创建机制不同于HttpSession,它会在每次页面刷新的时候都会重新创建,而销毁机制却是失去连接或者失效之后一定时间才会自动销毁,这样就可能造成服务端可能就保存了很多的无用的ScriptSession,所以不仅仅会影响性能问题,更重要的是,可能就不能实现你想要的功能。
解决方法是在接收消息的页面,也就是你调用dwr.engine.setActiveReverseAjax(true);的页面调用一个dwr的方法。

 

dwr.engine.setNotifyServerOnPageUnload(true);

 

这个方法的功能就是在销毁或刷新页面时销毁当前ScriptSession,这样就保证了服务端获取的ScriptSession集合中没有无效的ScriptSession对象。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值