springboot自动化配置mqtt,整合spring-integration-mqtt,连接多个mqtt
- mqtt整合
-
- 添加依赖
- 添加配置
- 工具类说明
- 订阅消息
- 发送消息
mqtt整合
最近有一个业务,要求连接多个非集群不同的mqtt服务,于是乎写了一个可根据配置动态配置的工具。starter-integration-mqtt整合了spring-integration-mqtt,只需添加配置,并实现消息订阅接口即可。可以实现订阅多个mqtt。
github源码:https://github.com/aLiang-xyl/integration-mqtt添加依赖
<dependency> <groupId>cn.xyliang</groupId> <artifactId>integration-mqtt-starter</artifactId> <version>0.0.2</version> </dependency>
添加配置
-
mqtt: config: channel1: #通道名称,可自定义,订阅消息时需要该名称 url: [tcp://host1:1883, tcp://host1:1883] #mqtt的url topics: [topic1, topic2] #监听的主题,和qos一一对应 qos: [1, 0] #监听主题的qos,和主题一一对应 username: admin #用户名 password: public #密码 timeout: 60 #连接超时时间,单位:秒 kep-alive-interval: 60 #心跳时间,单位:秒 async: true #发送消息时是否异步发送 client-id-append-ip: true #是否在clientId后面追加本机ip,因为clientid是唯一值,集群环境下不能使用相同的clientid,追加ip可解决该问题 consumer-client-id: consumer_client_test1 #consumer client id配置 producer-client-id: producer_client_test1 #producer client id配置 consumer-will: #consumer遗嘱消息配置 qos: 1 #遗嘱qos topic: will_topic #遗嘱主题 payload: '{"id": "consumer_client_test1"}' #遗嘱内容 retained: false #是否发送保留消息 producer-will: #producer遗嘱消息配置 qos: 1 #遗嘱qos topic: will_topic #遗嘱主题 payload: '{"id": "producer_client_test1"}' #遗嘱内容 retained: false #是否发送保留消息 channel2: #通道名称,第二个配置 url: [tcp://host1:1883, tcp://host1:1883] topics: [topic1, topic2] qos: [1, 0] username: admin password: public timeout: 60 kep-alive-interval: 60 async: true consumer-client-id: consumer_client_test2 producer-client-id: producer_client_test2 consumer-will: qos: 1 topic: will_topic payload: '{"id": "consumer_client_test2"}' retained: false producer-will: qos: 1 topic: will_topic payload: '{"id": "producer_client_test2"}' retained: false
工具类说明
MqttUtils工具类,用来发送mqtt消息
-
package cn.xyliang.mqtt.utils; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.integration.support.MessageBuilder; import org.springframework.messaging.Message; import lombok.extern.log4j.Log4j2; /** * <p> * 描述: mqtt工具类,可以根据通道名称发送消息 * </p> * * @author xingyl * @date 2020-04-01 10:16:35 */ @Log4j2 public class MqttUtils { /** * qos 0 */ public static final int QOS_0 = 0; /** * qos 1 */ public static final int QOS_1 = 1; /** * qos 2 */ public static final int QOS_2 = 2; private final static Map<String, MqttPahoMessageHandler> HANDLER_MAP = new HashMap<>(16); public final static String CHANNEL_NAME_SUFFIX = "MqttPahoMessageHandler"; /** * 存放handler * * @param channelName * @param handler */ public static void put(String channelName, MqttPahoMessageHandler handler) { HANDLER_MAP.put(channelName + CHANNEL_NAME_SUFFIX, handler); } /** * 发送消息 * * @param topic 要发送的主题 * @param message 消息内容 * @param qos qos级别 * @param channelName 发送到指定的通道 */ public static void sendMessage(String topic, String message, int qos, String channelName) { MqttPahoMessageHandler handler = getHandler(channelName); Message<String> mqttMessage = MessageBuilder.withPayload(message).setHeader(MqttHeaders.TOPIC, topic) .setHeader(MqttHeaders.QOS, qos).build(); handler.handleMessage(mqttMessage); } /** * 发送消息,默认qos级别为1 * * @param topic 要发送的主题 * @param message 消息内容 * @param channelName 发送到指定的通道 */ public static void sendMessage(String topic, String message, String channelName) { MqttPahoMessageHandler handler = getHandler(channelName); Message<String> mqttMessage = MessageBuilder.withPayload(message).setHeader(MqttHeaders.TOPIC, topic) .setHeader(MqttHeaders.QOS, QOS_1).build(); handler.handleMessage(mqttMessage); } /** * 发送消息 * * @param mqttMessage 消息 * @param channelName 发送到指定的通道 */ public static void sendMessage(Message<String> mqttMessage, String channelName) { MqttPahoMessageHandler handler = getHandler(channelName); handler.handleMessage(mqttMessage); } /** * 如果只有一个通道将使用该通道发送消息 * * @param topic * @param message * @param qos */ public static void sendMessage(String topic, String message, int qos) { MqttPahoMessageHandler handler = getDefaultHeadler(); Message<String> mqttMessage = MessageBuilder.withPayload(message).setHeader(MqttHeaders.TOPIC, topic) .setHeader(MqttHeaders.QOS, qos).build(); handler.handleMessage(mqttMessage); } /** * 如果只有一个通道将使用该通道发送消息,默认qos级别为1 * * @param topic * @param message */ public static void sendMessage(String topic, String message) { MqttPahoMessageHandler handler = getDefaultHeadler(); Message<String> mqttMessage = MessageBuilder.withPayload(message).setHeader(MqttHeaders.TOPIC, topic) .setHeader(MqttHeaders.QOS, QOS_1).build(); handler.handleMessage(mqttMessage); } /** * 如果只有一个通道将使用该通道发送消息,默认qos级别为1 * * @param mqttMessage 消息信息 */ public static void sendMessage(Message<String> mqttMessage) { MqttPahoMessageHandler handler = getDefaultHeadler(); handler.handleMessage(mqttMessage); } /** * 获取默认的handler * * @return */ private static MqttPahoMessageHandler getDefaultHeadler() { Collection<MqttPahoMessageHandler> values = HANDLER_MAP.values(); Iterator<MqttPahoMessageHandler> iterator = values.iterator(); MqttPahoMessageHandler handler = iterator.next(); if (handler == null) { log.error("发送消息失败,无可用的headler"); throw new RuntimeException("发送消息失败,无可用的headler"); } return handler; } /** * 根据通道获取handler * * @param channelName * @return */ private static MqttPahoMessageHandler getHandler(String channelName) { MqttPahoMessageHandler handler = HANDLER_MAP.get(channelName + CHANNEL_NAME_SUFFIX); if (handler == null) { log.error("未查询到相应通道{}的handler,存在的通道名称{}", channelName, HANDLER_MAP.keySet()); throw new IllegalArgumentException("未查询到相应通道" + channelName + "的handler"); } return handler; } }
订阅消息
订阅消息需要实现MessageHandler接口
注意:@ServiceActivator(inputChannel = "channel1")
中的配置必须和yml配置文件里的channel保持一致,一个channel配置对应一个MessageHandler接口实现。 -
import org.springframework.integration.annotation.ServiceActivator; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHandler; import org.springframework.messaging.MessagingException; import org.springframework.stereotype.Component; import lombok.extern.log4j.Log4j2; /** * <p>描述:配置channel1消息处理 </p> * * @author xingyl * @date 2020年3月27日 下午6:33:35 */ @Log4j2 @Component public class MqttMessageHandler implements MessageHandler { @ServiceActivator(inputChannel = "channel1") @Override public void handleMessage(Message<?> message) throws MessagingException { log.info("收到消息---{}", message); } }
配置中每一个channel对应一个MessageHandler实现
发送消息
MqttUtils工具类中封装了多个发送消息的方法
github源码:https://github.com/aLiang-xyl/integration-mqtt
————————————————
版权声明:本文为CSDN博主「阿良~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_20280007/article/details/105250986