一、 jms消息传递模式:
1、点对点消息传递模式(P2P)
消息发送到一个特殊队列(queue), 消费者从队列获取消息,一条消息只能被只能被一个消费者消费;
2、发布/订阅消息传递模式(publish-subscribe)
消息被发送到一个主题上(topic),所有订阅了该主题的消费者,都能接收到消息。
二、springboot 集成activemq
1.1 pom文件
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-activemq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.0</version>
</dependency>
1.2 配置文件
spring:
activemq:
#ActiveMQ通讯地址
broker-url: tcp://121.41.80.152:61616
#用户名
user: admin
#密码
password: admin
#是否启用内存模式(就是不安装MQ,项目启动时同时启动一个MQ实例)
in-memory: false
packages:
#信任所有的包
trust-all: true
pool:
#是否替换默认的连接池,使用ActiveMQ的连接池需引入的依赖
enabled: false
1.3 配置 Queue 和 topic
@Configuration
@EnableJms
public class ActiveMQConfig {
@Bean
public Queue queue() {
return new ActiveMQQueue("springboot.queue") ;
}
//springboot默认只配置queue类型消息,如果要使用topic类型的消息,则需要配置该bean
@Bean
public JmsListenerContainerFactory jmsTopicListenerContainerFactory(ConnectionFactory connectionFactory){
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
//这里必须设置为true,false则表示是queue类型
factory.setPubSubDomain(true);
return factory;
}
@Bean
public Topic topic() {
return new ActiveMQTopic("springboot.topic") ;
}
}
1.4 生产者
@RestController
public class Producer {
@Autowired
private JmsMessagingTemplate jmsTemplate;
@Autowired
private Queue queue;
@Autowired
private Topic topic;
//发送queue类型消息
@GetMapping("/queue")
public void sendQueueMsg(String msg) {
jmsTemplate.convertAndSend(queue, msg);
}
//发送topic类型消息
@GetMapping("/topic")
public void sendTopicMsg(String msg) {
System.out.println("1111111111111111");
jmsTemplate.convertAndSend(topic, msg);
}
}
1.5 消费者
@Component
public class Consumer {
//接收queue类型消息
//destination对应配置类中ActiveMQQueue("springboot.queue")设置的名字
@JmsListener(destination="springboot.queue")
public void ListenQueue(String msg){
System.out.println("接收到queue消息:" + msg);
}
//接收topic类型消息
//destination对应配置类中ActiveMQTopic("springboot.topic")设置的名字
//containerFactory对应配置类中注册JmsListenerContainerFactory的bean名称
@JmsListener(destination="springboot.topic", containerFactory = "jmsTopicListenerContainerFactory")
public void ListenTopic(String msg){
System.out.println("接收到topic消息:" + msg);
}
}
1.6 测试
三、websocket 集成 activemq (topic模式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mqtt-websocket测试</title>
// 替换成你的本地地址或者cdn地址
<script src='js/jquery-1.7.2.min.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js"></script>
</head>
<body>
<div id="messages">
<button id="start_connect" onclick="connect_server()">连接</button>
<button id="stop_connect" onclick="dis_connect()">断开连接</button>
<br>
<input type="text" id="msg_input">
<button id="send_btn" onclick="send_msg()">发送</button>
</div>
<br>
<div id="ws_log"><p>日志</p><br></div>
<script>
var client;
// 订阅主题
var topic_name = '/test_mqtt_ws/web_client';
function connect_server() {
// 终端ID,可以随机,可以手动设定
// var clientID = "client-" + (Math.floor(Math.random() * 100000));
var clientID = 'web-0001';
// Activemq中间件地址
client = new Messaging.Client('127.0.0.1', 61614, clientID);
// 连接
client.connect({
// 根据需要选择
// userName: user,
// password: password,
// 连接成功
onSuccess: onConnect,
// 连接出错
onFailure: onFailure,
});
client.onConnect = onConnect;
client.onMessageArrived = onMessageArrived;
client.onConnectionLost = onConnectionLost;
}
// 显示输出内容
function ws_logs(str) {
$("#ws_log").append(str + "<br>");
}
// 建立连接
function onConnect() {
ws_logs("正在建立连接");
// 订阅Topic
client.subscribe(topic_name);
}
// 连接失败
function onFailure(failure) {
ws_logs("连接失败");
ws_logs(failure.errorMessage);
}
// 监听消息
function onMessageArrived(message) {
ws_logs(message.payloadString);
// 如果你传输的是Json数据,在这里就可以进行解析了
var json_obj = eval('(' + message.payloadString + ')')
if (json_obj.cmd == '1') {
// 执行操作
}
}
// 连接中断
function onConnectionLost() {
if (responseObject.errorCode !== 0) {
// client.clientId 可以获取到ClientID
ws_logs(client.clientId + ": " + responseObject.errorCode);
}
}
// 主动断开连接
function dis_connect() {
client.disconnect();
ws_logs("断开连接");
return false;
}
// 发送消息
function send_msg() {
var mqtt_msg_send = $('#msg_input').val();
if (mqtt_msg_send) {
message = new Messaging.Message(mqtt_msg_send);
message.destinationName = topic_name;
// 发送mqtt消息
client.send(message);
$('#msg_input').val("");
}
return false;
}
</script>
</body>
</html>
四、websocket 集成 activemq (queue模式)
<!DOCTYPE html>
<html>
<head>
<title>spring-boot-WebSocket-点对点式-home</title>
<link rel="stylesheet" type="text/css" value="">
</head>
<body>
<script src="js/jquery.min.js"></script>
<script src="js/sockjs.min.js"></script>
<script src="js/stomp.min.js"></script>
<script type="application/javascript">
var url = "ws://121.41.80.151:61614/stomp";
var login = "admin";
var passcode = "admin";
//监听的队列
destination = "FileQueue";
client = Stomp.client(url);
var onconnect = function(frame) {
client.subscribe(destination, function(message) {
console.log(message.body);
alert(message.body);
});
};
client.connect(login, passcode, onconnect);
</script>
</body>
</html>
</html>
五、 ActiveMQ默认支持的传输协议
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>