dwr3实现服务器向客服端精准推送消息实例详解

直接贴代码吧,具体请看代码注解,下面会附上资源源码,一个可运行的实例。

前期准备

目录结构:
这里写图片描述

资源引入:

jar包
commons-logging-1.1.1.jar
dwr.jar
最新dwr.jar可以去官网下载http://directwebremoting.org/dwr/downloads/index.html

js
engine.js
util.js
官网demo里面可找到

项目创建具体操作

修改web.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <!-- 加入dwr的支持 -->
    <servlet>
        <!--名字 -->
        <servlet-name>dwr-invoker</servlet-name>

        <!-- 引入核心类 -->
        <servlet-class>
            org.directwebremoting.servlet.DwrServlet
        </servlet-class>

        <!--能够从其他域请求true:开启; false:关闭--> 
        <init-param>
            <param-name>crossDomainSessionSecurity</param-name>
               <param-value>false</param-value>
        </init-param>

        <!--允许脚本标签远程--> 
        <init-param>
          <param-name>allowScriptTagRemoting</param-name>
          <param-value>true</param-value>
        </init-param>

        <init-param>
          <param-name>classes</param-name>
          <param-value>java.lang.Object</param-value>
        </init-param>

        <!-- commet方式  -->
        <init-param>
            <param-name>activeReverseAjaxEnabled</param-name>
            <param-value>true</param-value>
        </init-param>

         <!--commet and poll 方式-->
        <init-param>
           <param-name>initApplicationScopeCreatorsAtStartup</param-name>
           <param-value>true</param-value>
        </init-param>

        <init-param>
            <param-name>maxWaitAfterWrite</param-name>
            <param-value>3000</param-value>
        </init-param>

        <!--测试环境下,需要开启debug模式,线上环境需要关闭-->
        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>

        <init-param>
            <param-name>logLevel</param-name>
            <param-value>WARN</param-value>
        </init-param>

    </servlet>

    <!-- 登录的servlet -->
    <servlet>
        <servlet-name>LoginAction</servlet-name>
        <servlet-class>com.test.servlet.LoginAction</servlet-class>
    </servlet>

    <!-- 登录映射 -->
    <servlet-mapping>
        <servlet-name>LoginAction</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>

    <!-- drw 映射  注意servlet-name必须要一致,别犯低级错误 --> 
    <servlet-mapping>
    <servlet-name>dwr-invoker</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>

  <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>
</web-app>

在web.xml同级目录下创建dwr.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC  
    "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"  
    "http://getahead.org/dwr/dwr20.dtd"> 
<dwr>
    <!--allow段落里面定义的试DWR可以创建和转换的类。  -->
    <allow>

      <create creator="new" javascript="MessagePush">
       <param name="class" value="com.dwr.sendmessage.MessagePush"/>
      </create>

      <create creator="new" javascript="TestPush">
       <param name="class" value="com.dwr.sendmessage.Test"/>
      </create>

    </allow>
</dwr>
<!-- creator属性 是必须的 - 它用来指定使用那种创造器。
        new: 用Java的new关键字创造对象。还有其他的方式,这里不多介绍 -->

<!-- javascript属性 用于指定浏览器中这个被创造出来的对象的名字。你不能使用Javascript的关键字。 -->

创建java类 MessagePush

package com.dwr.sendmessage;

import javax.servlet.ServletException;

import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContextFactory;

public class MessagePush
{
    public void onPageLoad(String userId) {

        ScriptSession scriptSession = WebContextFactory.get().getScriptSession();

        scriptSession.setAttribute(userId, userId);

        DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();

        try {

               dwrScriptSessionManagerUtil.init();
               System.out.println("blood for blood");

        } catch (ServletException e) {

               e.printStackTrace();

        }

 }


}

创建java类 DwrScriptSessionManagerUtil

package com.dwr.sendmessage;

import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;

import org.directwebremoting.Container;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.directwebremoting.extend.ScriptSessionManager;
import org.directwebremoting.servlet.DwrServlet;

public class DwrScriptSessionManagerUtil extends DwrServlet{

    private static final long serialVersionUID = -7504612622407420071L;

    public void init()throws ServletException {

           Container container = ServerContextFactory.get().getContainer();
           ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);
           ScriptSessionListener listener = new ScriptSessionListener() {
                  public void sessionCreated(ScriptSessionEvent ev) {
                         HttpSession session = WebContextFactory.get().getSession();

                         String userId =((User) session.getAttribute("userinfo")).getHumanid()+"";
                         System.out.println("a ScriptSession is created!"+"用户id="+userId);
                         ev.getSession().setAttribute("userId", userId);
                  }
                  public void sessionDestroyed(ScriptSessionEvent ev) {
                         System.out.println("a ScriptSession is distroyed");
                  }
           };
           manager.addScriptSessionListener(listener);
    }
}


创建java类 User

package com.dwr.sendmessage;

public class User
{
    int humanid ; 
    String name ;
    public int getHumanid()
    {
        return humanid;
    }
    public void setHumanid(int humanid)
    {
        this.humanid = humanid;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }

}

创建java类 Test

package com.dwr.sendmessage;

import java.util.Collection;

import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;

public class Test{
    public void sendMessageAuto(String userid, String message){

        final String userId = userid;
        final String autoMessage = message;
        Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
            public boolean match(ScriptSession session){
                if (session.getAttribute("userId") == null)
                    return false;
                else
                    return (session.getAttribute("userId")).equals(userId);
            }
        }, new Runnable(){

            private ScriptBuffer script = new ScriptBuffer();

            public void run(){

                script.appendCall("showMessage", autoMessage);

                Collection<ScriptSession> sessions = Browser

                .getTargetSessions();

                for (ScriptSession scriptSession : sessions){
                    System.out.println("推送信息添加到scriptSession");
                    scriptSession.addScript(script);
                }
            }
        });
    }
}

创建servlet LoginAction


package com.test.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.dwr.sendmessage.User;

/**用户登录*/
public class LoginAction extends HttpServlet {
    private static final long serialVersionUID = -5216193301182504458L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Integer id = Integer.valueOf(request.getParameter("id"));
        String username = request.getParameter("username");
        HttpSession session = request.getSession();
        User user = new User();
        user.setHumanid(id);
        user.setName(username);

        session.setAttribute("userinfo", user);
        response.sendRedirect("index.jsp");
    }
}

创建登录jsp login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>登录页</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
  </head>
  <body>
   <form action="login.do" method="post">
     username:<input type="text" name="username" /><br />
     password:<input type="text" name="id" /><br />
     <input type="submit" value="Login" />
    </form>
  </body>
</html>

创建消息接受jsp index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>消息页</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  <script type='text/javascript' src='dwr/engine.js'></script>
  <script type='text/javascript' src='dwr/util.js'></script>
  <script type="text/javascript" src="dwr/interface/MessagePush.js"></script>
    <!-- dwr/interface/MessagePush.js 这个js是dwr虚拟生成的,并不存在于项目中
    但是访问项目名/dwr可以看js的引用路径,这个到底是怎么回事还没弄清楚 -->

  <script type="text/javascript">
        //通过该方法与后台交互,确保推送时能找到指定用户
         function onPageLoad(){
            var userId = '${userinfo.humanid}';
            MessagePush.onPageLoad(userId);

          }
         //推送信息
         function showMessage(autoMessage){
                alert(autoMessage);

        }
  </script>
  <!--  在onload中的三个函数都是必须的,
  dwr.engine.setActiveReverseAjax(true);
  没有这句话将在默认5分钟后退出该会话,保持一个长连接。存在堵塞
  dwr.engine.setNotifyServerOnPageUnload(true);
    这个方法的功能就是在销毁或刷新页面时销毁当前ScriptSession,
    这样就保证了服务端获取的ScriptSession集合中没有无效的ScriptSession对象。。
   -->
  <body onload="onPageLoad();dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);;"> 
    通知消息弹出页 <hr>
    <br>
    <div id="DemoDiv">注意点!</div>
  </body>
</html>

创建推送消息发送页jsp MyJsp.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>推送消息发送页</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.5.1.js"></script>
    <script type='text/javascript' src='dwr/engine.js'></script>
    <script type='text/javascript' src='dwr/util.js'></script>
    <script type='text/javascript' src='dwr/interface/TestPush.js'></script>

    <script type="text/javascript">

    function test() {
        var msg = document.getElementById("msgId").value;
        TestPush.sendMessageAuto(msg,"blood for blood");

    }
    </script>
  </head>

  <body>
    推送人id&nbsp;&nbsp;&nbsp;&nbsp;: <input type="text" name="msgId" id="msgId" /> <br />(本文中就是登录密码)

    <input type="button" value="发送" onclick="test()"  />

  </body>
</html>

到这里整个项目创建完毕!运行一下试试吧。领悟主要还是看自己
下面附上资源下载路径http://download.csdn.net/download/qq_33866778/9925623

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值