以下代码是ActiveMQ中的作为消费者的代码,我会以我自己的理解来逐行的讲解这段代码,同时我是一个小白,一定会有很多问题存在,我会尽可能的去翻阅更多的资料,如果还有问题欢迎大家指出。
// 订阅消息报警
@PostConstruct
public void alarm() {
try {
ConnectionFactory connectionFactory = ActiveMQutil.getAmqFactory();
Connection connection = connectionFactory.createConnection();
if(connection != null){
connection.start();
final javax.jms.Session session = connection.createSession(Boolean.TRUE, javax.jms.Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createTopic( "队列名" );
MessageConsumer messageConsumer = session.createConsumer(destination);
//生成线程池
final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
try {
//获取队列中消息
final MapMessage mapMessage = (MapMessage)message;
fixedThreadPool.execute(new Runnable() {
public void run() {
try {
//过滤掉空消息
if(mapMessage != null){
// 参数
String a= mapMessage.getString("a");
String b= mapMessage.getString("b");
String c= mapMessage.getString("c");
String d= mapMessage.getString("d");
// 生成消息发送
String msg = om.writeValueAsString(new AMQBroadcast(a,b,c,d));
// admin用户固定发送
sendOneMessage("admin", msg);
//查询用户列表,遍历推送
List<SysUser> userList = new ArrayList<>();
if (StringUtils.isNotEmpty(unitName)) {
userList = sysUserService.selectPropertyUserList(unitName);
}
if (CollectionUtils.isNotEmpty(userList)) {
for (SysUser entity : userList) {
sendOneMessage(entity.getUserName(), msg);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
//关闭amq链接
messageConsumer.close();
session.close();
connection.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
什么是ActiveMQ?
简单来说,就是一个消息队列应用服务器。
功能就是是两个不同的应用之间实现通讯。当然也不一定非要两个应用,也可以实现同一个应用,不同模块之间的消息通讯,这种情况我还没遇到过,以后遇到再为大家讲解。 他还支持多语言,前面说上面的代码是一个消费者的角度,其实他的生产者用的就是C#语言。刚才提到了生产者和消费者的概念,在这里简单说明,生产者就是发送这条消息的生产方,消费者就是接收这条消息的消费方他们之间其实还有一个Broker,叫做消息处理中心,这也很好理解,因为总得有一个东西来管理这些消息到底应该发给谁。
以上,只是为了方便大家以下的理解,我尽可能说的不专业一点,当然,我自己也并不专业。后面会单独发一章介绍这个ActiveMQ,包括RabbitMQ,RocketMQ
下面为大家介绍以上代码:
1.@PostConstruct注解,作用:使该方法在类启动时就执行。原因:我们本身就是作为消费者得去等待生产者发送这条消息,因此生产者与消费者之间的连接,一定是得在类启动时就建立。但一定不是绝对的,最起码作为生产者一方,连接一定是想什么时候建立就建立。
2.ConnectionFactory connectionFactory = ActiveMQutil.getAmqFactory();
ActiveMQutil.getAmqFactory()这个方法是自己写的,里面就是建立一个ActiveMQ的工厂
3.Connection connection = connectionFactory.createConnection();
connectionFactory.createConnection();这个方法就是用来创建一个连接;
4.connection.start(); 启动这个连接
5.final javax.jms.Session session = connection.createSession(Boolean.TRUE, javax.jms.Session.AUTO_ACKNOWLEDGE);
通过这个连接创建一个会话,这边会有一个事务的属性,事务就需要有一步提交的操作。createSession()该方法里面的两个参数就是说,我这个会话不需要我去手动的提交,直接自动提交。
6.Destination destination = session.createTopic( "队列名" );
这一操作就是我在这个会话中创建一个消息队列,我这一个会话中有很多队列,因为生产者和消费者不可能只进行一种消息的交互可以理解为一个队列就是一种通道,同理在生产者方也需要有这样一个队列,因为他需要把通道打通。其实队列不只有topic一种,还有一种是queue他们二者的区别大家可自行查阅,一查就明白了。
7.MessageConsumer messageConsumer = session.createConsumer(destination);
这一步就是要创建这个队列中的消费者了“consumer”直译过来不就是“消费者”,也正是这一步体现出我们是消费者的身份,如果我用的是createProducer()方法,那我们就是生产者的身份了。
8. final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);这个就是线程方面的东西了,就是创建了一个容量为2的线程池。线程放到后面单独的章节讲解。
9.
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
// 需求代码
}
})
这个就是生产者发消息了,你会在这里面接收到,相当于生产者调用onMessage方法,给你传了一个message的参数。
10.final MapMessage mapMessage = (MapMessage)message;
对着个参数进行一个类型的强转,方便我们后面去取这个参数。
11.
fixedThreadPool.execute(new Runnable() {
public void run() {
// 需求代码
}
})
这块就用到了我们上面创建的线程池了。
12.
// 参数
String a= mapMessage.getString("a");
String b= mapMessage.getString("b");
String c= mapMessage.getString("c");
String d= mapMessage.getString("d");
// om是ObjectMapper类型的变量
String msg = om.writeValueAsString(new AMQBroadcast(unitName,dt,msgType,content));
a,b,c,d就是我跟生产者方约定好的一些参数名,现在我把它取出来。并且放到我自定义的一个实体类中转为JSON格式的字符串
=========================================================================
至此,ActiveMQ中作为消费者的代码已经阅读完了,后面的就是我自己的业务逻辑处理了,因为我们的主题本来就是去阅读代码,所以下面的也一并阅读一下。
=========================================================================
首先,下面的逻辑就和WebSocket有关。我们就简单说一下WebSocket是什么。WebSocket 是一个持久化的协议,他就是为了实现客户端与服务器之间的通信,我觉得最显著的特点是服务端可以向客服端去发消息。这个后面也可以单独出一章来讲解,或者大家可以去搜一下,网上有很多对他的讲解。
13.sendOneMessage("admin", msg);
这个方法的方法体为:
public void sendOneMessage(String userName, String message) {
List<Session> sessionList = sessionPool.get(userName);
if(sessionList != null) {
sessionList.forEach(item -> {
try {
if (item != null) {
item.getAsyncRemote().sendText(message);
}
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
这块内容就是去给前端推送消息,而且他是点对点的推送,就是这个连接是谁跟我建立的我就给谁推送。这个大家了解了WebSocket后会更好理解
=========================================================================好了代码到这就结束了,下面就是我的业务需求了,就是这个消息我都需要发给谁了,就没啥意思了。
===========================stay hungry , stay foolish===========================