DWR实现服务器向客户端推送消息
原文链接 http://www.blogjava.net/stevenjohn/archive/2012/07/07/382447.html这片文章还是给了我很大帮助,再次表示感谢,下面我将这两天的研究详细记录下来备忘,也希望能帮助到像我一样的人。只写过程,不写原理(不是不写,而是有些地方我也不太懂),下面开始:
第一、在项目中引入dwr.jar,然后在web.xml中进行配置,配置如下:
<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文件,内容如下
<!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>
</alow>
</dwr>
这个是dwr的基本配置,MessagePush在页面的javascript中使用,com.huatech.messageremind.service.MessagePush实现了想要调用的方法,MessagePush我觉得就相当于java类中的一个映射,在javascript中使用MessagePush.java类中实现的方法,即可在dwr中调用。
第三,要想使用dwr,还要在你想要推送的页面中引入script,
<script type="text/javascript" src="<%=basepath%>dwr/engine.js"></script>
<script type="text/javascript" src="<%=basepath%>dwr/util.js"></script>
<script type="text/javascript" src="<%=basepath%>dwr/interface/MessagePush.js"></script>
可以看见,也引入了dwr.xml中配置的javascript,engine.js和util.js是必须引入的。
以上三点都是基本配置,没什么好说的,想使用dwr,就得这么做。
第四,实现消息的精准推送
消息推送简单,但是想实现精准推送就需要做一些别的操作了
1 在任何一个用户登录的时候,都需要将其userId或者其他唯一性标识放入session中,我放的是userId,
这里就以 userId为唯一性标识。
2 在载入想推送的页面时,需要onload一个我在MessagePush类中实现的方法,当然了,需要使用dwr调用
js的调用方法如下:
function onPageLoad(){
var userId = '${userinfo.humanid}';
MessagePush.onPageLoad(userId);
}
<body onload="dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);onPageLoad();> 在onload中的三个函数都是必须的,其中dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);是dwr中的函数。
MessagePush类中实现的方法如下:
public void onPageLoad(String userId) {
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
scriptSession.setAttribute(userId, userId);
DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();
try {
dwrScriptSessionManagerUtil.init();
} catch (ServletException e) {
e.printStackTrace();
}
}
大家注意到,onPageLoad方法中还有一个名为DwrScriptSessionManagerUtil的类,该类如下实现:
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);
}
}
第四步是最最重要的,为了第四步我研究了两天多,下面开始消息推送。
第五、消息推送
在你想要推送消息的时候,调用如下方法:
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即为你想推给消息的人,message为你想推送的消息,大家注意到这里script.appendCall("showMessage", autoMessage);
其中showMessage为在想推送的页面中的javascript方法,autoMessage是这个方法的参数,这样那个页面就能得到推送的内容了,至于如何展现,就看你的需要了。
至此,一个dwr消息精准推送的步骤就写完了,其实很多东西都不难,只是我们不知道该怎么用而已。
DWR实现服务器向客户端推送消息的更多相关文章
- 反向Ajax,实现服务器向客户端推送消息
反向Ajax的基本概念是客户端不必从服务器获取信息,服务器会把相关信息直接推送到客户端.这样做的目的是解决Ajax传统Web模型所带来的一个限制:实时信息很难从技术上解决.原因是,客户端必须联系服务器 ...
- 反向Ajax,实现服务器向客户端推送消息之 Comet
基于 HTTP 长连接.无须在浏览器端安装插件的“服务器推”技术为“Comet”. 下面将介绍两种 Comet 应用的实现模型. 基于 AJAX 的长轮询(long-polling)方式 AJAX 的 ...
- 服务端向客户端推送消息技术之websocket的介绍
websocket的介绍 在讲解WebSocket前,我们先来看看下面这种场景,在HTTP协议下,怎么实现. 需求: 在网站中,要实现简单的聊天,这种情况怎么实现呢?如下图: 当发送私信的时候,如果要 ...
- Android应用实现Push推送消息原理
本文介绍在Android中实现推送方式的基础知识及相关解决方案.推送功能在手机开发中应用的场景是越来起来了,不说别的,就我 们手机上的新闻客户端就时不j时的推送过来新的消息,很方便的阅 ...
- HTML5服务器推送消息的各种解决办法
摘要 在各种BS架构的应用程序中,往往都希望服务端能够主动地向客户端推送各种消息,以达到类似于邮件.消息.待办事项等通知. 往BS架构本身存在的问题就是,服务器一直采用的是一问一答的机制.这就意味着如 ...
- HTML5服务器推送消息的各种解决办法,html5服务器
HTML5服务器推送消息的各种解决办法,html5服务器 摘要 在各种BS架构的应用程序中,往往都希望服务端能够主动地向客户端推送各种消息,以达到类似于邮件.消息.待办事项等通知. 往BS架构本身存在 ...
- Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送
Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送, ...
- SignalR 实时推送消息
业务场景 以前做过一个东西,就是当数据库有数据更新的时候,能够自动更新到前台,那时候signalr还没出现的时候,需要自己实现轮询读库,对于数据库和程序都是比较郁闷的事情.现在利用SignalR解决数 ...
- 使用 SignalR与SSE(Sever sent event)向客户端推送提示信息
最近有个项目想把c/s的代码转成mvc的,这听起来并不困难. 如果UI和业务逻辑良好分离了的话,不会花太多的功夫,应该多数的内容都能重复利用. 但在实际的操作过程中,发现业务逻辑代码和UI提示全是混在 ...
随机推荐
- nginx代理 upstream轮询
问题描述 我有2个Tomcat 一个端口开启(8021),一个端口未开启(8022),在nginx里用upstream模块进行代理 ,代理的负载算法采用的是默认的轮询算法,配置成功后,访问页面时并没 ...
- 个人博客作业Week3(微软必应词典客户端的案例分析)
软件缺陷常常又被叫做Bug,即为计算机软件或程序中存在的某种破坏正常运行能力的问题.错误,或者隐藏的功能缺陷.缺陷的存在会导致软件产品在某种程度上不能满足用户的需要.IEEE729-1983对缺陷有一 ...
- Spring容器技术内幕之BeanDefinition类介绍
引言 org.springframework.beans.factory.config.BeanDefinition是配置文件< bean >元素标签在容器中地内部表示.< bean ...
- BZOJ4170:极光(CDQ分治)
Description "若是万一琪露诺(俗称rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她.对方表现出兴趣的话,那就慢慢地反问.在她考虑答案的时候,趁机逃吧.就算是很简单的问题,她 ...
- 课外知识----easy BCD
可以用来作系统之间的切换 使用方法略
- 单节点etcd配置
$ cat /etc/etcd/etcd.conf ETCD_DATA_DIR="/var/lib/etcd/default.etcd" #监听URL,用于与其他节点通讯 ETCD ...
- (2)free详解 (每周一个linux命令系列)
(2)free详解 (每周一个linux命令系列) linux命令 free详解 引言:今天的命令是用来看内存的free free 换一个套路,我们先看man free中对free的描述: Displ ...
- 为什么签名前要加"\x19Ethereum Signed Message:\n"
在以太坊中,可以找到关于上述破损的解释例子.以太坊有两种消息,交易
- 1499-luogu洛谷 后缀表达式
题目描述 所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级). 如:3*(5–2)+7对应 ...
- C# 语法三 抽象类和接口
1.抽象类 2.接口 一 抽象类 跟普通类的区别: a)用abstract标识类.抽象方法 b)抽象方法,只能声明,不能定义 c)抽象类不能实例化 二 接口 接口用interface标识,所有的成员( ...