應用場景:
擁有系統通告或者評價、留言等用戶交互功能的系統,常常會要求在通告發布的同時,在用戶的系統界面友善的彈出通告消息,這種業務需求稱之爲消息實時推送
實現:
一般的實現方式有多種,包括AJAX的短輪詢、長輪詢,這些方式都可以實現功能,但是都會對服務器端造成壓力,這篇文章主要介紹使用RabbitMQ來實現消息實時推送
業務邏輯圖:
第一步:客戶端管理員發佈消息
js代碼
$.ajax({
url: "xxx/xxx/msgController/publish", //後端業務接口
context: document.body,
success: function(){
console.log('消息發佈成功');
}});
後端業務代碼(使用fanout交換器——發佈/訂閱模式):
首先需要配置RabbitMQ和SpringBoot的整合,這裏不多加介紹,詳情可看另一篇文章–>[整合SpringBoot+RabbitMQ]
final String ExchangeName = "testMsg"; // 交換器名稱
Connection conn = connectionFactoryUtil.GetRabbitConnection();
Channel channel = conn.createChannel();
channel.exchangeDeclare(ExchangeName, "fanout"); // 聲明fanout交換器
String message = "今天下午五點開會,都不要遲到";
channel.basicPublish(ExchangeName, "", null, message.getBytes("UTF-8"));
//把消息再存入數據庫
xxxMapper.insert(xxxxx); //sql不多加說明
這一步走完,信息已經寫入到MQ的交換器中
注意這裏並沒有創建隊列,因爲按照業務需求,管理員發佈了一條消息,全部的在線用戶都會消費這個消息,也就是一個生產者,多個消費者的模式,如果在這裏創建隊列,則會產生一個用戶獲取到消息之後,隊列消息清空,別的用戶就無法獲取這個消息了。
第二步:客戶端從MQ獲取消息
首先配置環境,需要用到Stomp
RabbitMQ安裝Stomp插件
執行命令
rabbitmq-plugins enable rabbitmq_web_stomp
rabbitmq-plugins enable rabbitmq_web_stomp_examples
安裝完成之後重啓MQ,在控制檯可以看到如下信息
好了,接下來開始js獲取MQ消息:
創建3個HTML文件,來表示三個客戶端
html內容:
<!DOCTYPE HTML>
<html>
<head>
<title>My WebSocket</title>
</head>
<body style="text-align:center">
我是用戶11111111111111<br/>
我從MQ讀取到的消息是:
<span id="msg"></span>
<div id="message">
</div>
</body>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script>
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.js"></script>
<script src="http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
// 初始化 ws 對象
var ws = new WebSocket('ws://localhost:15674/ws');
// 獲得Stomp client對象
var client = Stomp.over(ws);
// 定義連接成功回調函數
var on_connect = function(x) {
//data.body是接收到的數據
client.subscribe("/exchange/testMsg", function(data) {
var msg = data.body;
$("#msg").text(msg);
});
};
// 定義錯誤時回調函數
var on_error = function() {
console.log('error');
};
// 連接RabbitMQ
client.connect('guest', 'guest', on_connect, on_error, '/');
</script>
</html>
注意:js請求的是後端新增的交換器
client.subscribe("/exchange/testMsg", function(data) {
var msg = data.body;
$("#msg").text(msg);
});
原理:QabbitMQ中的fanout交換器——發佈/訂閱模式,默認是沒有隊列的,當有n個消費者連接交換器的時候,交換器會自動創建n個隊列供一個消費者使用,隊列名是一串隨機字符串
client除了subscribe方法之外,還有一些方法可供選擇
client.subscribe(destination,callback,headers) :訂閱消息
client.send(destination,headers,body):發佈消息
client.unsubscribe(id):取消訂閱,id爲訂閱時返回的編號
client.onreceive:默認接收回調從臨時隊列獲取消息
打開三個html頁面,可以看到如下結果:
1、已經拿到MQ的信息
2、打開MQ控制檯,可以看到 testMsg 交換器創建了三個隨機隊列
小結:
技術有限、歡迎點評