Springboot + DWR 实现消息推送详解编程语言

SpringBoot 整合 dwr ,实现 js 直接调用后端 Service.

前一段时间由于工作需要接触到了dwr,使用dwr将mq接收到的消息推送到前台,最近项目改用springboot,因此又去重新回炉了一下。
1.新建springboot项目,添加下面dwr的依赖文件

       <!-- DWR --> 
        <dependency> 
            <groupId>org.directwebremoting</groupId> 
            <artifactId>dwr</artifactId> 
            <version>3.0.2-RELEASE</version> 
        </dependency> 

2.添加spring.xml,配置dwr扫描
spring.xml 内容:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"> 
 
    <dwr:annotation-config/> 
 
    <dwr:annotation-scan scanRemoteProxy="false" base-package="com.hikvision.lcc.dwr"/> 
 
    <dwr:configuration/> 
</beans> 
 

springboot 需要加载spring.xml,在启动类中做如下配置:

@SpringBootApplication 
@ImportResource("classpath*:spring/spring.xml") 
public class Demo2Application { 
    public static void main(String[] args) { 
        SpringApplication.run(Demo2Application.class, args); 
    } 
} 
  1. 之前项目用到的是dwr.xml进行配置,在springboot中我们需要用Java代码进行配置,配置类如下:
 
@Configuration 
public class DwrConfig { 
 
    /** 
     *  加入 DWR servlet,相当于在xml中配置 
     * @return 
     */ 
    @Bean 
    public ServletRegistrationBean servletRegistrationBean() { 
       DwrSpringServlet servlet = new DwrSpringServlet(); 
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(servlet, "/dwr/*"); 
        //设置成true使DWR能够debug和进入测试页面。 
        registrationBean.addInitParameter("debug", "true"); 
        //pollAndCometEnabled 设置成true能增加服务器的加载能力,尽管DWR有保护服务器过载的机制。 
        registrationBean.addInitParameter("pollAndCometEnabled", "true"); 
         
        registrationBean.addInitParameter("activeReverseAjaxEnabled", "true"); 
        registrationBean.addInitParameter("maxWaitAfterWrite", "60"); 
        return registrationBean; 
    } 
} 
 

4.基本配置结束,先写个小小的demo一下。新建一个service类

@Service 
@RemoteProxy  // spring 的注解,相当于暴露服务 
public class DemoDwr { 
    //TODO  这块可以注入服务 
    @RemoteMethod 
    public String hello(){ 
        return "hello  dada " ; 
    } 
    @RemoteMethod 
    public String echo(String  string){ 
        return "hello   " + string ; 
    } 
} 

接着写一个简单的html来个阶段性测试。
demo.html

<html> 
<head> 
    <title></title> 
    <script type='text/javascript' src='/dwr/engine.js'></script> 
    <script type='text/javascript' src='/dwr/interface/DemoDwr.js'></script> 
     
</head> 
hello 
<script> 
    DemoDwr.echo('叫我小司马', function (str) { 
        alert(str); 
    }); 
</script> 
</html> 

运行项目,刷新一下页面就可以感受到自己的劳动成果了。

5.接着我简单演示一下如何从后端推送到前端消息。

先写一个DWR工具类DwrScriptSessionManagerUtil,可以直接拷贝,一般变化不大。

public class DwrScriptSessionManagerUtil extends DwrServlet { 
    private static final long serialVersionUID = -7504612622407420071L; 
    public void init(final String key, final String value) 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(key, value); 
            } 
            public void sessionDestroyed(ScriptSessionEvent ev) { 
                System.out.println("a ScriptSession is distroyed"); 
            } 
        }; 
        manager.addScriptSessionListener(listener); 
 
    } 
 
} 

假如你已经有一个加收消息的类DemoConsumer,如果mq不熟悉的建议先补一补去,在这我就不细说了。我的消费者代码大概如下,牵扯到业务会自行略去。

@Service 
@RemoteProxy 
public class Demo2Consumer extends AbstractSpringNotifyConsumer { 
   //保存scriptSession , 这个方法需要在页面刚已加载的时候调用,为了前端和后端建立连接。 
    @RemoteMethod 
    public void onPageLoad(String tag) { 
        //获取当前的ScriptSession 
        try { 
            ScriptSession scriptSession =  WebContextFactory.get().getScriptSession(); 
            if(scriptSession != null){ 
                scriptSession.setAttribute("tag", tag); 
            } 
            DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil() ; 
            dwrScriptSessionManagerUtil.init("tag",tag); 
        } catch (Exception e) { 
 
        } 
        System.out.println("onPageLoad 被调用 :" + tag); 
    } 
 
  // mq接受到消息会触发这个方法 
 @Override 
    public void onMessage(TextNotifyMessage message) throws NotifyException { 
 
        System.out.println(" 收到消息  " + message.getData()); 
        System.err.println(" 收到消息  " + message.getData()); 
        // 下面代码变化不大,主要是给前端推送 
        Browser.withAllSessionsFiltered(new ScriptSessionFilter() { 
 
            public boolean match(ScriptSession session) { 
                /* 这块判断是否合法 ,可以在这块验证用户的合法性,为了简单我直接返回true*/ 
                return true; 
                  /*  if (session.getAttribute("userId") == null) { 
                        return false; 
                    } else { 
                        return (session.getAttribute("userId")).equals(userId); 
                    }*/ 
            } 
 
        }, new Runnable() { 
            private ScriptBuffer script = new ScriptBuffer(); 
 
            public void run() { 
                //设定前台接收消息的方法和参数  在前台js里定义getmessage (data) 的方法,就会自动被调用 
                script.appendCall("getmessage", message.getData()); 
                Collection<ScriptSession> sessions = Browser.getTargetSessions(); 
                for (ScriptSession scriptSession : sessions) { 
                    scriptSession.addScript(script); 
                } 
                System.out.println("dwrtool  showmessage 调用 "); 
            } 
        }); 
    } 
} 
  1. 现在再来改改原来的html,
<html> 
<head> 
    <title></title> 
    <script type='text/javascript' src='/dwr/engine.js'></script> 
 
    <script type='text/javascript' src='/dwr/interface/Demo2Consumer.js'></script> 
 
    <script> 
        function onpage(){ 
            // 页面加载直接调用这个函数,我这块使用点击按钮 
            Demo2Consumer.onPageLoad("123456"); 
        } 
        // 后端会调用这个函数 
        function getmessage(data){ 
            alert(data); 
        } 
    </script> 
</head> 
hello 
<input type="button" onclick="onpage()" value="onpage" > 
</html> 

效果展示:点击onpage 按钮后会一直对话框弹出,显示的就是mq接收到的消息。
7.补充,和前端聊了聊以后,前端给建议不需要调用onpage记载,也可以调用dwr的js函数,这块我贴上供大家参考

 
<script> 
    //  激活ajax     
  dwr.engine.setActiveReverseAjax(true) 
    // 页面未加载的时候是否发送通知 
    dwr.engine.setNotifyServerOnPageUnload(true,true) 
    // 出现错误后的处理方法 
    dwr.engine.setErrorHandler(function(){}) 
 
    function getmessage(data){ 
        if (window.eventBus) { 
            window.eventBus.$emit('getDwr',data); 
        } 
    } 
</script> 
 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/16547.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论