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

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

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

   

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

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

  

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

   这个是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. "-//W3C//DTD HTML 4.01 Transitional//EN">  
  7.   
  8.     
  9.     "<%=basePath%>">  
  10.     DWR  DEMO  
  11.     "pragma" content="no-cache">  
  12.     "cache-control" content="no-cache">  
  13.     "expires" content="0">      
  14.     "keywords" content="keyword1,keyword2,keyword3">  
  15.     "description" content="This is my page">  
  16.     
  17.   'text/javascript' src='dwr/engine.js'>  
  18.   'text/javascript' src='dwr/util.js'>  
  19.   "text/javascript" src="dwr/interface/MessagePush.js">  
  20.   
  21.   "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.     
  34.   "onPageLoad();dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);;">   
  35.     This is my DWR DEOM page. 
      
  36.     
      
  37.     "DemoDiv">demo
  
  •     
  •   
  •     以上代码的简单解释:

         页面页面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. "-//W3C//DTD HTML 4.01 Transitional//EN">  
    7.   
    8.     
    9.     "<%=basePath%>">  
    10.     My JSP <span class="string" style="color:#0000FF;">'MyJsp.jsp'</span> starting page  
    11.     "pragma" content="no-cache">  
    12.     "cache-control" content="no-cache">  
    13.     "expires" content="0">      
    14.     "keywords" content="keyword1,keyword2,keyword3">  
    15.     "description" content="This is my page">  
    16.     "text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.5.1.js">  
    17.     'text/javascript' src='dwr/engine.js'>  
    18.     'text/javascript' src='dwr/util.js'>  
    19.     'text/javascript' src='dwr/interface/TestPush.js'>  
    20.       
    21.     "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.       
    30.     
    31.     
    32.     
    33.     id    : "text" name="msgId" id="msgId" />   
    34.      
    35.     "button" value="Send" οnclick="test()"  />  
    36.       
    37.     
    38.   

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

     
    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 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实现服务器端向客户端精确推送消息)