基于RabbitMQ的消息推送
以前,浏览器中的推送功能通过轮询实现。但是这种模式的缺点是浏览器需要不断地向服务器发出请求,每次请求中的绝大部分数据都是相同的,里面包含的有效数据可能只是很小的一部分,这导致占用很多的带宽,而且不断地连接将大量消耗服务器资源。HTML5定义了WebSocket,它能够实现浏览器与服务器之间全双工通信。其优点有两个:一是服务器与客户端之间交换的标头信息很小;而是服务器可以主动传送数据给客户端。
1.启用Web stomp插件
在RabbitMQ的sbin目录下执行
rabbitmq-plugins enable rabbitmq_web_stomp
2.创建一个gradle项目
创建目录结构
其中红色的文件夹不用创建,gradle会自动创建。
添加依赖的包
在build.grdle的dependencies中增加
3.创建生产者
package com.study.produce;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Random;
/**
* @author jiayq
*/
public class StompProduce {
public static void main(String[] args) throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
ConnectionFactory factory = (ConnectionFactory) applicationContext.getBean("factory");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare("exchange_stomp", "topic");
channel.queueDeclare("queue_stomp", false, false, false, null);
channel.queueBind("queue_stomp", "exchange_stomp", "*.test");
while (true) {
String message = new String(new Random().nextDouble()+"");
channel.basicPublish("exchange_stomp", "test.test",
null, message.getBytes());
System.out.println("message:\t" + message);
Thread.sleep(3 * 1000);
}
}
}
4.创建消费者(订阅者)
在resources中的webapp中增加如下目录
其中jquery.min.js和stomp.js可以在网上下载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>RabbitMqPublish socket</title>
<script type="text/javascript" src="stomp.js"></script>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<script type="text/javascript">
$(document).ready(function () {
//创建客户端
var client = Stomp.client("ws://localhost:15674/ws");
//定义连接成功回调函数
var onConnect = function () {
//订阅商品折扣主题的消息
client.subscribe("/exchange/exchange_stomp/test.test", function (message) {
//弹出业务消息提醒
$("#body").append("\t" + message.body + "<br/>");
});
};
//定义错误时回调函数
var onError = function (msg) {
$("#body").html(msg);
};
//连接服务器
client.connect("guest", "guest", onConnect, onError);
client.heartbeat.incoming = 5000;
client.heartbeat.outgoing = 5000;
});
</script>
<body>
<div id="body"></div>
</body>
</html>
5.运行
打开界面,然后启动生产者
6.总结
在JavaScript中与STOMP服务器通信,首先要创建一个STOMP对象,调用Stomp.clent(url)函数。
例子中的localhost是RabbitMQ服务器的地址,在实际使用时可以改成服务器的IP地址,插件默认监听15674端口,在stomp.js中使用ws://URL格式。
在stomp.js中用connect函数连接服务器。前两个参数是用户名和密码,后两个时候成功与失败的回调。
个人认为,RabbitMQ最大的优势在于提供了比较灵活的消息路由策略,高可用性、可靠性,以及丰富的插件、多种平台支持和完善的文档。不过,由于AMQP协议本身导致它的实现比较重量,从而使得与其他MQ(比如Kafka)对比其吞吐量处于下风。