spring boot 整合activemq 進行服務端訊息推送(web頁面)
阿新 • • 發佈:2019-02-16
最近公司的專案裡有需要服務端向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時,前端頁面都能實時的讀取到並執行相應的業務邏輯。