首页 > 代码库 > DWR3实现服务器端向客户端精确推送消息

DWR3实现服务器端向客户端精确推送消息

原贴地址:http://blog.csdn.net/luojia_wang/article/details/8825929

研究了一天半,终于模拟出了这个功能,网上DWR的资料不少,但是真正实现客户端向服务器端精确推送消息的只有两篇文章。但是代码都只有一部分,向我这种刚开始学习DWR的人来说要看懂真的蛮难。不过即便如此,http://www.blogjava.net/stevenjohn/archive/2012/07/07/382447.html这片文章还是给了我很大帮助,再次表示感谢,下面我将这两天的研究详细记录下来备忘,也希望能帮助到像我一样的人。只写过程,不写原理(不是不写,而是有些地方我也不太懂),下面开始:

         第一、在项目中引入dwr.jar,然后在web.xml中进行配置,配置如下:

   

Java代码 
  1. <servlet>  
  2.   
  3.         <servlet-name>dwr-invoker</servlet-name>  
  4.   
  5.         <servlet-class>  
  6.   
  7.             org.directwebremoting.servlet.DwrServlet  
  8.   
  9.         </servlet-class>  
  10.   
  11.         <init-param>  
  12.   
  13.             <param-name>crossDomainSessionSecurity</param-name>  
  14.   
  15.                <param-value>false</param-value>  
  16.   
  17.             </init-param>  
  18.   
  19.         <init-param>  
  20.   
  21.           <param-name>allowScriptTagRemoting</param-name>  
  22.   
  23.           <param-value>true</param-value>  
  24.   
  25.         </init-param>  
  26.   
  27.         <init-param>  
  28.   
  29.           <param-name>classes</param-name>  
  30.   
  31.           <param-value>java.lang.Object</param-value>  
  32.   
  33.         </init-param>  
  34.   
  35.         <init-param>  
  36.   
  37.             <param-name>activeReverseAjaxEnabled</param-name>  
  38.   
  39.             <param-value>true</param-value>  
  40.   
  41.         </init-param>  
  42.   
  43.         <init-param>  
  44.   
  45.            <param-name>initApplicationScopeCreatorsAtStartup</param-name>  
  46.   
  47.            <param-value>true</param-value>  
  48.   
  49.         </init-param>  
  50.   
  51.         <init-param>  
  52.   
  53.             <param-name>maxWaitAfterWrite</param-name>  
  54.   
  55.             <param-value>3000</param-value>  
  56.   
  57.         </init-param>  
  58.   
  59.         <init-param>  
  60.   
  61.             <param-name>debug</param-name>  
  62.   
  63.             <param-value>true</param-value>  
  64.   
  65.         </init-param>  
  66.   
  67.         <init-param>  
  68.   
  69.             <param-name>logLevel</param-name>  
  70.   
  71.             <param-value>WARN</param-value>  
  72.   
  73.         </init-param>  
  74.   
  75.     </servlet>  

   第二:在web.xml的同级目录下新建dwr.xml文件,内容如下

  

Java代码 
  1. <!DOCTYPE dwr PUBLIC  
  2.      "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"  
  3.      "http://getahead.org/dwr/dwr30.dtd">  
  4.   
  5. <dwr>  
  6.      <alow>  
  7.           <create creator="new" javascript="MessagePush">  
  8.             <param name="class" value=http://www.mamicode.com/"com.huatech.messageremind.service.MessagePush"/>  
  9.          </create>  
  10.           <create creator="new" javascript="TestPush">  
  11.             <param name="class" value=http://www.mamicode.com/"com.huatech.messageremind.service.Test"/>  
  12.          </create>  
  13.      </alow>  
  14. </dwr>  

   这个是dwr的基本配置,MessagePush在页面的javascript中使用,这个是对被推送页面开放的java类,Test是对推送页面开放的java类。场景:管理员后台登陆,发布一条消息,通过Test推送到后台,后台通过MessagePush推送给指定的用户,当然,至于怎么找到指定的用户,下面会说。

     第三,被推送的页面代码

    

Java代码 
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  7. <html>  
  8.   <head>  
  9.     <base href=http://www.mamicode.com/"<%=basePath%>">  
  10.     <title>DWR  DEMO</title>  
  11.     <meta http-equiv="pragma" content="no-cache">  
  12.     <meta http-equiv="cache-control" content="no-cache">  
  13.     <meta http-equiv="expires" content="0">      
  14.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  15.     <meta http-equiv="description" content="This is my page">  
  16.   </head>  
  17.   <script type=‘text/javascript‘ src=http://www.mamicode.com/‘dwr/engine.js‘></script>  
  18.   <script type=‘text/javascript‘ src=http://www.mamicode.com/‘dwr/util.js‘></script>  
  19.   <script type="text/javascript" src=http://www.mamicode.com/"dwr/interface/MessagePush.js"></script>  
  20.   
  21.   <script type="text/javascript">  
  22.         //通过该方法与后台交互,确保推送时能找到指定用户  
  23.          function onPageLoad(){  
  24.             var userId = ‘${userinfo.humanid}‘;  
  25.             MessagePush.onPageLoad(userId);  
  26.   
  27.           }  
  28.          //推送信息  
  29.          function showMessage(autoMessage){  
  30.                 alert(autoMessage);  
  31.                   
  32.         }  
  33.   </script>  
  34.   <body onload="onPageLoad();dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);;">   
  35.     This is my DWR DEOM page. <hr>  
  36.     <br>  
  37.     <div id="DemoDiv">demo</div>  
  38.   </body>  
  39. </html>  

    以上代码的简单解释:

     页面页面onload的3个函数都是必须的,后两个是dwr的,第一个是将登录用户的userid与对应   的scriptSession进行处理,以便精确推送的时候能找到推送对象

第四 MessagePush类中实现的方法如下:

  

Java代码 
  1.      public void onPageLoad(String userId) {  
  2.   
  3.        ScriptSession scriptSession = WebContextFactory.get().getScriptSession();  
  4.   
  5.        scriptSession.setAttribute(userId, userId);  
  6.   
  7.        DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();  
  8.   
  9.        try {  
  10.   
  11.               dwrScriptSessionManagerUtil.init();  
  12.               System.out.println("cacaca");  
  13.   
  14.        } catch (ServletException e) {  
  15.   
  16.               e.printStackTrace();  
  17.   
  18.        }  
  19.   
  20. }  

 

 

里面对应的DwrScriptSessionManagerUtil 对应如下:

 

Java代码 
  1. import javax.servlet.ServletException;  
  2. import javax.servlet.http.HttpSession;  
  3.   
  4. import org.directwebremoting.Container;  
  5. import org.directwebremoting.ServerContextFactory;  
  6. import org.directwebremoting.WebContextFactory;  
  7. import org.directwebremoting.event.ScriptSessionEvent;  
  8. import org.directwebremoting.event.ScriptSessionListener;  
  9. import org.directwebremoting.extend.ScriptSessionManager;  
  10. import org.directwebremoting.servlet.DwrServlet;  
  11.   
  12. public class DwrScriptSessionManagerUtil extends DwrServlet{  
  13.   
  14.     private static final long serialVersionUID = -7504612622407420071L;  
  15.   
  16.     public void init()throws ServletException {  
  17.   
  18.            Container container = ServerContextFactory.get().getContainer();  
  19.            ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);  
  20.            ScriptSessionListener listener = new ScriptSessionListener() {  
  21.                   public void sessionCreated(ScriptSessionEvent ev) {  
  22.                          HttpSession session = WebContextFactory.get().getSession();  
  23.   
  24.                          String userId =((User) session.getAttribute("userinfo")).getHumanid()+"";  
  25.                          System.out.println("a ScriptSession is created!");  
  26.                          ev.getSession().setAttribute("userId", userId);  
  27.                   }  
  28.                   public void sessionDestroyed(ScriptSessionEvent ev) {  
  29.                          System.out.println("a ScriptSession is distroyed");  
  30.                   }  
  31.            };  
  32.            manager.addScriptSessionListener(listener);  
  33.     }  
  34. }  

 第五 推送页面代码:

    

Java代码 
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  7. <html>  
  8.   <head>  
  9.     <base href=http://www.mamicode.com/"<%=basePath%>">  
  10.     <title>My JSP ‘MyJsp.jsp‘ starting page</title>  
  11.     <meta http-equiv="pragma" content="no-cache">  
  12.     <meta http-equiv="cache-control" content="no-cache">  
  13.     <meta http-equiv="expires" content="0">      
  14.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  15.     <meta http-equiv="description" content="This is my page">  
  16.     <script type="text/javascript" src=http://www.mamicode.com/"<%=request.getContextPath() %>/js/jquery-1.5.1.js"></script>  
  17.     <script type=‘text/javascript‘ src=http://www.mamicode.com/‘dwr/engine.js‘></script>  
  18.     <script type=‘text/javascript‘ src=http://www.mamicode.com/‘dwr/util.js‘></script>  
  19.     <script type=‘text/javascript‘ src=http://www.mamicode.com/‘dwr/interface/TestPush.js‘></script>  
  20.       
  21.     <script type="text/javascript">  
  22.       
  23.     function test() {  
  24.         var msg = document.getElementById("msgId").value;  
  25.         //msg = {msgId: ‘1‘, context: $("#msgContext").val()};  
  26.         TestPush.sendMessageAuto(msg,"哈哈哈");  
  27.           
  28.     }  
  29.     </script>  
  30.   </head>  
  31.     
  32.   <body>  
  33.     id&nbsp;&nbsp;&nbsp;&nbsp;: <input type="text" name="msgId" id="msgId" /> <br />  
  34.      
  35.     <input type="button" value=http://www.mamicode.com/"Send" onclick="test()"  />  
  36.       
  37.   </body>  
  38. </html>  

 第六:精确推送要实现的代码:

 

Java代码 
  1. public class Test{  
  2.     public void sendMessageAuto(String userid, String message){  
  3.           
  4.         final String userId = userid;  
  5.         final String autoMessage = message;  
  6.         Browser.withAllSessionsFiltered(new ScriptSessionFilter() {  
  7.             public boolean match(ScriptSession session){  
  8.                 if (session.getAttribute("userId") == null)  
  9.                     return false;  
  10.                 else  
  11.                     return (session.getAttribute("userId")).equals(userId);  
  12.             }  
  13.         }, new Runnable(){  
  14.               
  15.             private ScriptBuffer script = new ScriptBuffer();  
  16.               
  17.             public void run(){  
  18.                   
  19.                 script.appendCall("showMessage", autoMessage);  
  20.                   
  21.                 Collection<ScriptSession> sessions = Browser  
  22.   
  23.                 .getTargetSessions();  
  24.                   
  25.                 for (ScriptSession scriptSession : sessions){  
  26.                     scriptSession.addScript(script);  
  27.                 }  
  28.             }  
  29.         });  
  30.     }  
  31. }  

 至此   这个例子的代码都已经贴出来了,应该是可以跑通的,有问题的话可以给我留言。当然,要自己写个登录,然后把userId放到session里面,这个比较简单,就不贴代码了,有问题可以在http://download.csdn.net/detail/luojia_wang/5275588上下载原项目。我只是简单的做了一个能实现功能的例子,还有很多地方要研究,比如跟spring整合,还可能有很多优化,等我继续学习一下再说.

DWR3实现服务器端向客户端精确推送消息