您的位置:首页 > 其它

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

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

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

Java代码

<servlet>

<servlet-name>dwr-invoker</servlet-name>

<servlet-class>

org.directwebremoting.servlet.DwrServlet

</servlet-class>

<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>

<init-param>

<param-name>activeReverseAjaxEnabled</param-name>

<param-value>true</param-value>

</init-param>

<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>

<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>

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

Java代码

<!DOCTYPE dwr PUBLIC

"-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"

"http://getahead.org/dwr/dwr30.dtd">

<dwr>

<alow>

<create creator="new" javascript="MessagePush">

<param name="class" value="com.huatech.messageremind.service.MessagePush"/>

</create>

<create creator="new" javascript="TestPush">

<param name="class" value="com.huatech.messageremind.service.Test"/>

</create>

</alow>

</dwr>

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

第三,被推送的页面代码

Java代码

<%@ 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>DWR DEMO</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>

<script type="text/javascript">

//通过该方法与后台交互,确保推送时能找到指定用户

function onPageLoad(){

var userId = '${userinfo.humanid}';

MessagePush.onPageLoad(userId);

}

//推送信息

function showMessage(autoMessage){

alert(autoMessage);

}

</script>

<body onload="onPageLoad();dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);;">

This is my DWR DEOM page. <hr>

<br>

<div id="DemoDiv">demo</div>

</body>

</html>

以上代码的简单解释:

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

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

Java代码

public void onPageLoad(String userId) {

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

scriptSession.setAttribute(userId, userId);

DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();

try {

dwrScriptSessionManagerUtil.init();

System.out.println("cacaca");

} catch (ServletException e) {

e.printStackTrace();

}

}

里面对应的DwrScriptSessionManagerUtil 对应如下:

Java代码

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!");

ev.getSession().setAttribute("userId", userId);

}

public void sessionDestroyed(ScriptSessionEvent ev) {

System.out.println("a ScriptSession is distroyed");

}

};

manager.addScriptSessionListener(listener);

}

}

第五 推送页面代码:

Java代码

<%@ 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>My JSP 'MyJsp.jsp' starting page</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;

//msg = {msgId: '1', context: $("#msgContext").val()};

TestPush.sendMessageAuto(msg,"哈哈哈");

}

</script>

</head>

<body>

id    : <input type="text" name="msgId" id="msgId" /> <br />

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

</body>

</html>

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

Java代码

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){

scriptSession.addScript(script);

}

}

});

}

}

至此 这个例子的代码都已经贴出来了,应该是可以跑通的,有问题的话可以给我留言。当然,要自己写个登录,然后把userId放到session里面,这个比较简单,就不贴代码了,有问题可以在http://download.csdn.net/detail/luojia_wang/5275588上下载原项目。我只是简单的做了一个能实现功能的例子,还有很多地方要研究,比如跟spring整合,还可能有很多优化,等我继续学习一下再说.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: