spring boot 整合activemq 进行服务端消息推送(web页面)

最近公司的项目里有需要服务端向web端实时推送消息的需求,网上搜索了一番,有前端页面通过定时任务向后台发送ajax请求刷新,有使用第三方提供的消息服务(GoEasy),前者因为会有很多请求是无用的,容易加大服务器负荷造成宕机,后者现在收费了(免费的也只能用一年并且使用上有所限制)。后来在网上看到activemq可以通过ajax请求访问订阅消息,于是便想到用activemq来实现此功能并记录下来,供自己以及需要帮助的程序员朋友参考学习。

1. 我项目使用的spring boot并且maven依赖的,下面贴出activemq的maven依赖:
<dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-broker</artifactId>
            <version>5.15.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/activemq-broker-5.15.2.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-client</artifactId>
            <version>5.15.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/activemq-client-5.15.2.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-kahadb-store</artifactId>
            <version>5.15.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/activemq-kahadb-store-5.15.2.jar</systemPath>
        </dependency> 
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-spring</artifactId>
            <version>5.15.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/activemq-spring-5.15.2.jar</systemPath>
        </dependency> 
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>hawtbuf</artifactId>
            <version>1.11</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/hawtbuf-1.11.jar</systemPath>
        </dependency> 
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-web</artifactId>
            <version>5.15.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/activemq-web-5.15.2.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>javax.jms</groupId>
            <artifactId>jms</artifactId>
            <version>1.1</version>
        </dependency>
这里要说明一下,我这里是把activemq的jar包放在了本地,所以采用这种本地依赖方式。

2.  接着是后台向activemq发送消息的代码:
public class ActiveMQUtil {
    /**
         * 发送消息至mq
         * @param topic     主题
         * @param message   消息内容
         */
        public static void sendMessage(String topic, String message){
            ConnectionFactory connectionFactory; 
            Connection connection = null;
            Session session; 
            Destination destination; 
            MessageProducer producer; 
            // 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
            connectionFactory = new ActiveMQConnectionFactory(
                    ActiveMQConnection.DEFAULT_USER,
                    ActiveMQConnection.DEFAULT_PASSWORD, Const.MQ_BROKEN_URL);

            try { // 构造从工厂得到连接对象
                connection = connectionFactory.createConnection();
                // 启动
                connection.start();
                // 获取操作连接
                session = connection.createSession(Boolean.TRUE,
                        Session.AUTO_ACKNOWLEDGE); 
                destination = session.createTopic(topic);
                // 得到消息生成者【发送者】
                producer = session.createProducer(destination);   
                // 设置不持久化,实际根据项目决定
    //            producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
                // 构造消息
                TextMessage textMsg = session.createTextMessage();
                textMsg.setText(message);
                producer.send(destination, textMsg);
                session.commit();
            } catch (Exception e) { 
                e.printStackTrace();
            } finally {
                try {
                    if (null != connection)
                        connection.close();
                } catch (Throwable ignore) {
                }
            }
        }
}
3 向spring boot中注入activemq处理ajax请求的servlet,代码片段如下:
   /**
     * 注入activemq的ajax控制器
       @Bean
    public ServletRegistrationBean ajaxServletRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean(new AjaxServlet());
    registration.setEnabled(true);
        registration.addUrlMappings("/amq/*");
        return registration;
    }
    //向servletContext中初始化activemq的消息访问url
    @Bean
    public ServletContextInitializer initializer() {
        return new ServletContextInitializer() {

            @Override
            public void onStartup(ServletContext servletContext) throws ServletException {
                servletContext.setInitParameter("org.apache.activemq.brokerURL",    "tcp://localhost:61616");
            }
        };
    }

4 代码里调用发送消息的工具类方法,比如商品下架了,要给商户发送通知消息:

    //msg为topic,可根据项目实际情况自由决定
    ActiveMQUtil.sendMessage("msg","您的商品被下架了");

5 前台页面ajax调用:
5.1 先要引入activemq的ajax插件:
由于我使用的是基于jQuery的adapter,所以还要引入jQuery,另外amq_jquery_adapter.js和amq.js在下载的activemq的压缩包中\webapps-demo\demo\js目录下有(ajax功能好像是5.6以后版本才有的)。

<script src="jquery.min.js?v=2.1.4"></script>
<script src="amq_jquery_adapter.js"></script>
<script src="amq.js"></script>

5.2 接着是js调用:

window.onload = function() {
            var amq = org.activemq.Amq;
            amq.init({ uri: '/amq', logging: false, timeout: 45, clientId:'test1' });
            var myHandler ={
                rcvMessage: function(message){
                    //接收到消息后,自己的业务处理逻辑
                }
            };
            amq.addListener('test1','topic://msg',myHandler.rcvMessage);
            //test1为消费者的一个ID,接受到消息回调时会用到作为标识 
            //topic://msg表示主题订阅目的地
};

说明:
uri为前面注入activemq的ajax控制器时定义的访问url;
Clientid表示浏览器的身份,如果用同一个字符串,则只有一个窗口会生效;如果用时间或者登陆的用户id或其他唯一值做参数时,那么每一个浏览器窗口就相当于不同的消费者。
myHandler接收到消息之后的回调函数

以上就是项目中使用activemq进行消息推送接收的代码片段,目前已经在生产环境完美运行,当后台发送消息到activemq时,前端页面都能实时的读取到并执行相应的业务逻辑。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值