标签:des c style class blog code
闲来无事,把自己关于对dwr消息推送的实现过程描述一番。
首先第一步,当然在工程中是加入dwr.jar了,接着在web.xml中配置以下代码
<servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/config/dwr.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <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>logLevel</param-name> <param-value>WARN</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping>
从配置中可以看出需要新建一个dwr配置文件,如下
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr//dwr30.dtd"> <dwr> <allow> <!-- <create javascript="udao" creator="spring"> <param name="beanName" value="udao" /> <include method="getUserPage"/> </create> <convert converter="bean" match="com.cpsoft.app.web.domain.PageModel" /> --> <create javascript="MessagePush" creator="spring"> <param name="beanName" value="messagePush" /> </create> <convert converter="bean" match="java.lang.StackTraceElement" /> <convert converter="exception" match="java.lang.Exception" /> </allow> </dwr>
那么大家可以看到,我配置了一个messagePush这个对象,那么我就来说说这个对象吧
@Component public class MessagePush { 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()); private ScriptSessionListener listener; private boolean isInit = false; public boolean isInit(){ return isInit; } /** * 获取scriptSession的监听对象,只需要实例化一次 * @return */ public ScriptSessionListener getListener() { if(listener == null){ listener = new ScriptSessionListener() { public void sessionCreated(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<String, Staff> onlineStaffMap = CacheUtil.getOnlineStaffMap(); //获取当前的在线用户 if(!onlineStaffMap.containsKey(staff.getId())) onlineStaffMap.put(staff.getId(), staff); //如果不存在,则将当前用户加入到缓存中 } if(!isInit) isInit = true; } public void sessionDestroyed(ScriptSessionEvent ev) { String userId = (String) ev.getSession().getAttribute(SCRIPT_SESSION_USERID); log.info("a ScriptSession["+userId+"] is distroyed!"); } }; } return listener; } /** * 初始化dwr监听,只在程序中调用一次即可 */ public void init(){ 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的方式向前台推送消息 * @param userId 用户Id * @param autoMessage 消息内容 */ private static void sendMessageAuto(final String userId, final String autoMessage) { Browser.withAllSessionsFiltered(new ScriptSessionFilter() { public boolean match(ScriptSession session) { String id = (String) session.getAttribute(MessagePush.SCRIPT_SESSION_USERID); if (id == null || !userId.equals(id)) { //匹配接收人的Id return false; } return true; } }, new Runnable() { private ScriptBuffer script = new ScriptBuffer(); public void run() { script.appendCall(MessagePush.SCRIPT_SESSION_MSG, autoMessage); //推送消息(我在这里用的是json字符串) Collection<ScriptSession> sessions = Browser.getTargetSessions(); //获取当前的目标客户端对象 for (ScriptSession scriptSession : sessions) { scriptSession.addScript(script); } } }); }
说到这里,后台工作就告一段落了,接着来说说前台,首先引入js吧
<!-- 消息推送 --> <script type=‘text/javascript‘ src=‘${ctx}/dwr/engine.js‘></script> <script type=‘text/javascript‘ src=‘${ctx}/dwr/util.js‘></script> <script type="text/javascript" src="${ctx}/dwr/interface/MessagePush.js"></script>
在onload 加入
<body onload="dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);">
那么现在大工告成了,只要后台调用上面的推送方法,前台就好自动触发
function showMessage(autoMessage){ //alert(autoMessage); if(!callCometShowMsg){ eval("var json="+ autoMessage); g_showTip("消息类型:"+json.MESSAGE_TYPE+"<br />消息内容:"+json.MESSAGE_DATA); }else{ callCometShowMsg(autoMessage); } }
最后说说总结一下把,实测了一下,发现Ie8下反应慢一点,对于chrome,我用的这个版本会有问题, 火狐表现良好
有什么问题可以留言,看到第一时间回复
标签:des c style class blog code
原文地址:http://www.cnblogs.com/lljj/p/3759531.html