zoukankan      html  css  js  c++  java
  • dwr消息推送

    闲来无事,把自己关于对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,我用的这个版本会有问题, 火狐表现良好

    有什么问题可以留言,看到第一时间回复

  • 相关阅读:
    经典SQL例题
    truncate,delete,drop的异同点
    scp 在不同主机之间数据传输
    自定义标签库
    servlet 学习
    HTTP协议 学习
    Tomcat服务器的数字证书 HTTPS 连接!
    JSP开发 路径问题汇总
    java 文件上传 下载 总结
    myeclipse 出现换行符和空格符 解决方案 换行出现乱码
  • 原文地址:https://www.cnblogs.com/lljj/p/3759531.html
Copyright © 2011-2022 走看看