闲来无事,把自己关于对dwr消息推送的实现过程描述一番。
首先第一步,当然在工程中是加入dwr.jar了,接着在web.xml中配置以下代码
dwr-invoker
org.directwebremoting.servlet.DwrServlet
config
/WEB-INF/config/dwr.xml
debug
true
crossDomainSessionSecurity
false
allowScriptTagRemoting
true
classes
java.lang.Object
activeReverseAjaxEnabled
true
initApplicationScopeCreatorsAtStartup
true
maxWaitAfterWrite
3000
logLevel
WARN
2
dwr-invoker
/dwr/*
从配置中可以看出需要新建一个dwr配置文件,如下
<?xml version="1.0" encoding="UTF-8"?>
/p>
"-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
"http://getahead.org/dwr//dwr30.dtd">
那么大家可以看到,我配置了一个messagePush这个对象,那么我就来说说这个对象吧
@Componentpublic classMessagePush {final public static String SCRIPT_SESSION_USERID = "SCRIPT_SESSION_USERID";final public static String SCRIPT_SESSION_MSG = "showMessage"; //这是页面上当后台消息推送时,自动触发的js方法名称
private Logger log = Logger.getLogger(this.getClass());privateScriptSessionListener listener;private boolean isInit = false;public booleanisInit(){returnisInit;
}/*** 获取scriptSession的监听对象,只需要实例化一次
*@return
*/
publicScriptSessionListener getListener() {if(listener == null){
listener= newScriptSessionListener() {public voidsessionCreated(ScriptSessionEvent ev) {
HttpSession session=WebContextFactory.get().getSession();
Staff staff=SessionUtil.getStaff(session);if(staff!=null){
ev.getSession().setAttribute(SCRIPT_SESSION_USERID, staff.getId());//与当前登录用户相关联
log.info("a ScriptSession["+staff.getId()+"] is created!");
Map onlineStaffMap = CacheUtil.getOnlineStaffMap(); //获取当前的在线用户
if(!onlineStaffMap.containsKey(staff.getId())) onlineStaffMap.put(staff.getId(), staff); //如果不存在,则将当前用户加入到缓存中
}if(!isInit) isInit = true;
}public voidsessionDestroyed(ScriptSessionEvent ev) {
String userId=(String) ev.getSession().getAttribute(SCRIPT_SESSION_USERID);
log.info("a ScriptSession["+userId+"] is distroyed!");
}
};
}returnlistener;
}/*** 初始化dwr监听,只在程序中调用一次即可*/
public voidinit(){if(listener == null){
Container container=ServerContextFactory.get().getContainer();
ScriptSessionManager manager=container
.getBean(ScriptSessionManager.class);
manager.addScriptSessionListener(getListener());
log.info("the dwr client is inited!");
}
}
}
这个类的主要作用是初始化监听,接着如果有了监听,那现在就可以推送消息了,请看代码
/*** 采用dwr的方式向前台推送消息
*@paramuserId 用户Id
*@paramautoMessage 消息内容*/
private static void sendMessageAuto(final String userId, finalString autoMessage) {
Browser.withAllSessionsFiltered(newScriptSessionFilter() {public booleanmatch(ScriptSession session) {
String id=(String) session.getAttribute(MessagePush.SCRIPT_SESSION_USERID);if (id == null || !userId.equals(id)) { //匹配接收人的Id
return false;
}return true;
}
},newRunnable() {private ScriptBuffer script = newScriptBuffer();public voidrun() {
script.appendCall(MessagePush.SCRIPT_SESSION_MSG, autoMessage);//推送消息(我在这里用的是json字符串)
Collection sessions =Browser.getTargetSessions(); //获取当前的目标客户端对象for(ScriptSession scriptSession : sessions) {
scriptSession.addScript(script);
}
}
});
}
说到这里,后台工作就告一段落了,接着来说说前台,首先引入js吧
在onload 加入
那么现在大工告成了,只要后台调用上面的推送方法,前台就好自动触发
functionshowMessage(autoMessage){//alert(autoMessage);
if(!callCometShowMsg){
eval("var json="+autoMessage);
g_showTip("消息类型:"+json.MESSAGE_TYPE+"
消息内容:"+json.MESSAGE_DATA);
}else{
callCometShowMsg(autoMessage);
}
}
最后说说总结一下把,实测了一下,发现Ie8下反应慢一点,对于chrome,我用的这个版本会有问题, 火狐表现良好
有什么问题可以留言,看到第一时间回复
原文:http://www.cnblogs.com/lljj/p/3759531.html