SpringBoot组件开发-基于eclipse paho 的MQTT 客户端
主题: 基于Java 8 、SpringBoot 2.5.15 仿造Rocket MQ Spring组件开发一个MQTT组件
核心目标
开发一个基于 SpringBoot 的 MQTT 客户端组件,通过注解驱动实现消息处理器的自动注册和消息路由,支持智能重连机制和配置化管理。
关键特性
-
注解驱动开发 :通过
@MqttTopic
注解声明消息处理器 -
智能重连机制:支持指数退避策略的自动重连
-
配置化管理 :通过
MqttProperties
统一管理连接参数 -
泛型消息处理:支持自动反序列化 JSON 消息到指定类型
-
通配符订阅 :支持 MQTT 标准的
+
和#
通配符

组件说明
- 配置层 (绿色)
MqttProperties
:连接参数配置(broker、认证等)ReconnectConfig
:重连策略配置application.yml
:外部配置文件
- 核心层 (橙色)
EnhancedMqttFactory
:MQTT 客户端工厂(Builder模式)MqttClientWrapper
:客户端包装类(连接管理)SmartReconnectCallback
:智能重连核心实现MqttHandlerRegistry
:消息处理器注册中心MqttCallback
:默认消息回调路由
- 注解接口层 (蓝色)
@MqttTopic
:主题订阅注解MqttMessageHandler
:消息处理接口
核心流程
- 启动初始化

- 消息处理流程

- 断线重连流程

关键设计
- Builder模式 :
EnhancedMqttFactory
使用 Builder 模式灵活创建客户端 - 退避重连策略 :支持
initialDelay + backoffFactor
的指数退避 - 动态主题解析 :支持 Spring 占位符
${}
和 MQTT 通配符 - 泛型消息处理:自动推导处理器声明的消息类型
- 线程安全设计 :使用
CopyOnWriteArraySet
管理订阅主题 - 优雅关闭 :实现
DisposableBean
确保资源释放
最终实现效果
java
import com.alibaba.fastjson2.JSON;
import com.hm.framework.mqtt.MqttMessageHandler;
import com.hm.framework.mqtt.MqttTopic;
import org.springframework.stereotype.Component;
@MqttTopic("${pdc.topic:testDemo/#}")
@Component
public class DemoHandler implements MqttMessageHandler<DemoMsg> {
@Override
public void handle(String topic, DemoMsg message) {
System.out.println("topic: " + topic);
System.out.println("message: " + JSON.toJSONString(message));
}
}
输入

输出
topic: testDemo/123 message: {"age":5,"msg":"测试消息","name":"张三"}
开始
一、maven依赖
xml
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
二、源码core
1. @MqttTopic注解 ,配合@Component与MqttMessageHandler接口实现配置化topic+自动定略
java
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MqttTopic {
String value();
/**
* 消息质量等级(默认0)
*/
int qos() default 0;
}
2. MqttMessageHandler泛型接口,通过Spring上下文动态获取MqttMessageHandler接口Bean,接收并解析消息成对应类型
java
public interface MqttMessageHandler <T>{
void handle(String topic,T message);
}
3. MqttProperties Spring 配置
java
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.List;
@ConfigurationProperties(prefix = "mqtt")
public class MqttProperties {
/**
* MQTT broker URL
*/
private String broker;
/**
* MQTT 客户端 ID
*/
private String clientId;
/**
* MQTT 用户名
*/
private String username;
/**
* MQTT 密码
*/
private char[] password;
/**
* 是否清除会话
*/
private boolean cleanSession = true;
/**
* MQTT 订阅的 topic
*/
private List<String> topics = new ArrayList<>();
/**
* 重连配置
*/
private ReconnectConfig reconnect = new ReconnectConfig();
public static class ReconnectConfig {
/**
* 最大重连次数
*/
private int maxAttempts = Integer.MAX_VALUE;
/**
* 初始重连延迟(毫秒)
*/
private long initialDelay = 5000;
/**
* 重连延迟乘数因子
*/
private double backoffFactor = 1.5;
/**
* 是否自动重连初始连接
*/
private boolean autoRetryInitialConnect = true;
public int getMaxAttempts() {
return maxAttempts;
}
public void setMaxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
}
public long getInitialDelay() {
return initialDelay;
}
public void setInitialDelay(long initialDelay) {
this.initialDelay = initialDelay;
}
public double getBackoffFactor() {
return backoffFactor;
}
public void setBackoffFactor(double backoffFactor) {
this.backoffFactor = backoffFactor;
}
public boolean isAutoRetryInitialConnect() {
return autoRetryInitialConnect;
}
public void setAutoRetryInitialConnect(boolean autoRetryInitialConnect) {
this.autoRetryInitialConnect = autoRetryInitialConnect;
}
}
public String getBroker() {
return broker;
}
public void setBroker(String broker) {
this.broker = broker;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public char[] getPassword() {
return password;
}
public void setPassword(char[] password) {
this.password = password;
}
public boolean isCleanSession() {
return cleanSession;
}
public void setCleanSession(boolean cleanSession) {
this.cleanSession = cleanSession;
}
public ReconnectConfig getReconnect() {
return reconnect;
}
public void setReconnect(ReconnectConfig reconnect) {
this.reconnect = reconnect;
}
public List<String> getTopics() {
return topics;
}
public void setTopics(List<String> topics) {
this.topics = topics;
}
}
4. MQTT客户端工厂类
java
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* MQTT 工厂类,用于创建具有智能重连功能的 MQTT 客户端
*/
public class EnhancedMqttFactory {
// MQTT 代理地址
private final String broker;
// 客户端ID
private final String clientId;
// 存储持久化策略
private final MemoryPersistence persistence;
// 用户名
private final String username;
// 密码
private final char[] password;
// 是否使用清洁会话
private final boolean cleanSession;
// 自定义回调
private final MqttCallback customCallback;
// 重连配置
private final ReconnectConfig reconnectConfig;
// 创建日志记录器实例
private final Logger logger = LoggerFactory.getLogger(EnhancedMqttFactory.class);
/**
* 构造函数私有化,采用 Builder 模式创建实例
*/
private EnhancedMqttFactory(Builder builder) {
this.broker = builder.broker;
this.clientId = builder.clientId + "_" + System.currentTimeMillis();
this.persistence = builder.persistence;
this.username = builder.username;
this.password = builder.password;
this.cleanSession = builder.cleanSession;
this.customCallback = builder.customCallback;
this.reconnectConfig = builder.reconnectConfig;
}
/**
* Builder 类,用于构建 EnhancedMQTTFactory 实例
*/
public static class Builder {
// 必需参数
private final String broker;
// 可选参数
private String clientId = UUID.randomUUID().toString();
private MemoryPersistence persistence = new MemoryPersistence();
private String username;
private char[] password;
private boolean cleanSession = true;
private MqttCallback customCallback;
private ReconnectConfig reconnectConfig = new ReconnectConfig();
public Builder(String broker) {
this.broker = broker;
}
public Builder clientId(String clientId) {
this.clientId = clientId;
return this;
}
public Builder persistence(MemoryPersistence persistence) {
this.persistence = persistence;
return this;
}
public Builder credentials(String username, char[] password) {
this.username = username;
this.password = password;
return this;
}
public Builder cleanSession(boolean cleanSession) {
this.cleanSession = cleanSession;
return this;
}
public Builder callback(MqttCallback callback) {
this.customCallback = callback;
return this;
}
public Builder reconnectConfig(ReconnectConfig config) {
this.reconnectConfig = config;
return this;
}
public EnhancedMqttFactory build() {
return new EnhancedMqttFactory(this);
}
}
/**
* 创建并返回一个 MQTT 客户端包装类实例
* @return MQTT 客户端包装类实例
* @throws MqttException 如果客户端创建过程中出现错误
*/
public MqttClientWrapper create() throws MqttException {
logger.info("创建 MQTT 客户端,broker: {}, clientId: {}", broker, clientId);
MqttClient client = new MqttClient(broker, clientId, persistence);
MqttConnectOptions connOpts = buildConnectOptions();
SmartReconnectCallback callback = buildCallback(client, connOpts);
client.setCallback(callback);
performConnect(client, connOpts, callback);
return new MqttClientWrapper(client, callback);
}
/**
* 构建 MQTT 连接选项
* @return MQTT 连接选项实例
*/
private MqttConnectOptions buildConnectOptions() {
MqttConnectOptions opts = new MqttConnectOptions();
if (username != null && password != null) {
opts.setUserName(username);
opts.setPassword(password);
}
opts.setCleanSession(cleanSession);
return opts;
}
/**
* 构建智能重连回调实例
* @param client MQTT 客户端
* @param opts 连接选项
* @return 智能重连回调实例
*/
private SmartReconnectCallback buildCallback(MqttClient client, MqttConnectOptions opts) {
return customCallback != null ?
new SmartReconnectCallback(client, opts, reconnectConfig, customCallback) :
new SmartReconnectCallback(client, opts, reconnectConfig);
}
/**
* 执行 MQTT 客户端连接
* @param client MQTT 客户端
* @param opts 连接选项
* @param callback 智能重连回调
* @throws MqttException 如果连接过程中出现错误
*/
private void performConnect(MqttClient client, MqttConnectOptions opts,
SmartReconnectCallback callback) throws MqttException {
try {
logger.info("尝试连接 MQTT 代理");
client.connect(opts);
logger.info("成功连接到 MQTT 代理");
} catch (MqttException e) {
logger.error("连接 MQTT 代理失败: {}", e.getMessage());
if (reconnectConfig.autoRetryInitialConnect) {
logger.info("自动重连功能已启用,将尝试重新连接");
callback.scheduleReconnectAttempt();
}
throw e;
}
}
/**
* 重连配置参数封装
*/
public static class ReconnectConfig {
int maxAttempts = Integer.MAX_VALUE;
long initialDelay = 5000;
double backoffFactor = 1.5;
boolean autoRetryInitialConnect = true;
public ReconnectConfig maxAttempts(int max) {
this.maxAttempts = max;
return this;
}
public ReconnectConfig initialDelay(long delayMs) {
this.initialDelay = delayMs;
return this;
}
public ReconnectConfig backoffFactor(double factor) {
this.backoffFactor = factor;
return this;
}
public ReconnectConfig autoRetryInitialConnect(boolean enable) {
this.autoRetryInitialConnect = enable;
return this;
}
}
/**
* 智能重连回调(核心实现)
*/
protected static class SmartReconnectCallback implements MqttCallback {
private final MqttClient client;
private final MqttConnectOptions connOpts;
private final ReconnectConfig config;
private final MqttCallback userCallback;
private final Set<String> subscribedTopics = new CopyOnWriteArraySet<>();
private volatile boolean isShutdown = false;
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private final AtomicInteger reconnectAttempts = new AtomicInteger(0);
// 创建日志记录器实例
private final Logger logger = LoggerFactory.getLogger(SmartReconnectCallback.class);
SmartReconnectCallback(MqttClient client, MqttConnectOptions opts,
ReconnectConfig config) {
this(client, opts, config, null);
}
SmartReconnectCallback(MqttClient client, MqttConnectOptions opts,
ReconnectConfig config, MqttCallback userCallback) {
this.client = client;
this.connOpts = opts;
this.config = config;
this.userCallback = userCallback;
}
@Override
public void connectionLost(Throwable cause) {
if (isShutdown) return;
logger.warn("MQTT 连接丢失: {}", cause.getMessage());
// 处理连接丢失事件
handleDisconnection(cause);
// 转发事件到用户回调
forwardEvent(() -> userCallback.connectionLost(cause));
}
@Override
public void messageArrived(String topic, MqttMessage message) {
if(logger.isDebugEnabled()){
logger.debug("收到来自主题 {} 的消息: {}", topic, new String(message.getPayload()));
}
// 转发事件到用户回调
forwardEvent(() -> {
try {
userCallback.messageArrived(topic, message);
} catch (Exception e) {
logger.error("处理消息时发生错误: {}", e.getMessage());
throw new RuntimeException(e);
}
});
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
if(logger.isDebugEnabled()){
logger.debug("消息投递完成: {}", token.isComplete() ? "成功" : "失败");
}
// 转发事件到用户回调
forwardEvent(() -> userCallback.deliveryComplete(token));
}
private void handleDisconnection(Throwable cause) {
// 如果重连次数未达到最大值,则尝试重连
if (reconnectAttempts.get() < config.maxAttempts) {
long delay = calculateBackoffDelay();
logger.info("将在 {}.{}s 后尝试第{}次重连", delay / 1000, delay % 1000 / 100, reconnectAttempts.incrementAndGet());
scheduler.schedule(this::attemptReconnect, delay, TimeUnit.MILLISECONDS);
} else {
logger.error("已达到最大重连次数,停止重连");
}
}
private long calculateBackoffDelay() {
// 计算重连延迟时间
return (long) (config.initialDelay * Math.pow(config.backoffFactor, reconnectAttempts.get()));
}
private synchronized void attemptReconnect() {
// 尝试重连
try {
if (!client.isConnected()) {
client.connect(connOpts);
logger.info("重连成功!");
reconnectAttempts.set(0);
// 重连成功后重新订阅主题
resubscribeTopics();
}
} catch (MqttException e) {
logger.error("重连失败: {}", e.getMessage());
handleDisconnection(e);
}
}
private void resubscribeTopics() {
if (!subscribedTopics.isEmpty()) {
try {
for (String topic : subscribedTopics) {
client.subscribe(topic);
logger.info("重新订阅主题: {}", topic);
}
} catch (MqttException e) {
logger.error("重新订阅主题失败: {}", e.getMessage());
}
}
}
void scheduleReconnectAttempt() {
// 立即尝试重连
scheduler.schedule(this::attemptReconnect, 0, TimeUnit.MILLISECONDS);
}
private void forwardEvent(Runnable action) {
// 转发事件到用户回调
if (userCallback != null) {
try {
action.run();
} catch (Exception e) {
logger.error("用户回调执行异常: {}", e.getMessage());
}
}
}
public void shutdown() {
this.isShutdown = true;
try {
if (!scheduler.isShutdown()) {
scheduler.shutdownNow();
if (!scheduler.awaitTermination(3, TimeUnit.SECONDS)) {
logger.warn("重连调度器未正常关闭");
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public void addSubscribedTopic(String topic) {
subscribedTopics.add(topic);
}
}
}
5.MQTT客户端包装类
java
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
/**
* MQTT客户端包装类
*/
public class MqttClientWrapper implements DisposableBean {
private final Logger logger = LoggerFactory.getLogger(MqttClientWrapper.class);
private final MqttClient client;
private final EnhancedMqttFactory.SmartReconnectCallback callback;
public MqttClientWrapper(MqttClient client, EnhancedMqttFactory.SmartReconnectCallback callback) {
this.client = client;
this.callback = callback;
}
public MqttClient getClient() {
return client;
}
public EnhancedMqttFactory.SmartReconnectCallback getCallback() {
return callback;
}
public void subscribe(String topic) throws MqttException {
callback.addSubscribedTopic(topic);
client.subscribe(topic);
}
public void publish(String topic, byte[] payload, int qos, boolean retained) throws MqttException {
if(logger.isDebugEnabled()){
logger.debug("发布消息到主题: {}, Qos: {}, Retained: {}", topic, qos, retained);
}
client.publish(topic, payload, 0, false);
}
public void publish(String topic, MqttMessage message) throws MqttException, MqttPersistenceException {
if(logger.isDebugEnabled()){
logger.debug("发布消息到主题: {}, Qos: {}", topic, message.getQos());
}
client.publish(topic, message);
}
public synchronized void shutdown() {
try {
String clientId = client.getClientId();
if (client.isConnected()) {
logger.info("MQTTClientWrapper clientId:{} closing...",clientId);
client.disconnect(); // 优雅断开连接
}
logger.info("MQTTClientWrapper clientId:{} closed.", clientId);
client.close(true); // 强制关闭客户端
if (callback != null) {
logger.info("MQTTClientWrapper clientId:{} callback shutdown.",clientId);
callback.shutdown(); // 关闭回调线程池
}
} catch (MqttException e) {
logger.error("客户端关闭异常: {}", e.getMessage());
}
}
@Override
public void destroy() throws Exception {
this.shutdown();
}
}
6. 消息处理器
java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* MQTT 消息处理器注册
*/
public class MqttHandlerRegistry {
private static final Logger logger = LoggerFactory.getLogger(MqttHandlerRegistry.class);
private final Map<Pattern, HandlerWrapper<?>> handlerMap = new ConcurrentHashMap<>();
private final TypeFactory typeFactory = TypeFactory.defaultInstance();
@Autowired
private ObjectMapper objectMapper;
@Autowired
private Environment env;
@Autowired
public void registerHandlers(ObjectProvider<MqttMessageHandler<?>> handlers) {
handlers.forEach(handler -> {
MqttTopic annotation = handler.getClass().getAnnotation(MqttTopic.class);
if (annotation != null) {
Class<?> payloadType = resolvePayloadType(handler);
registerHandler(handler, payloadType, annotation);
}
});
}
private void registerHandler(
MqttMessageHandler<?> handler,
Class<?> payloadType,
MqttTopic annotation
) {
//如果是spring ${}, 则替换为环境变量的值
String value = env.resolvePlaceholders(annotation.value());
String patternStr = value
.replace("+", "[^/]+")
.replace("#", ".*");
Pattern pattern = Pattern.compile(patternStr);
handlerMap.put(pattern, new HandlerWrapper<>(
handler,
payloadType,
value,
annotation.qos()
));
logger.info("注册处理器 [主题: {}] => {}", value, handler.getClass());
}
@SuppressWarnings("unchecked")
private <T> Class<T> resolvePayloadType(MqttMessageHandler<?> handler) {
Type[] interfaces = handler.getClass().getGenericInterfaces();
ParameterizedType type = (ParameterizedType) interfaces[0];
Type actualType = type.getActualTypeArguments()[0];
return (Class<T>) typeFactory.constructType(actualType).getRawClass();
}
public void processMessage(String topic, byte[] payload) {
handlerMap.entrySet().stream()
.filter(entry -> entry.getKey().matcher(topic).matches())
.forEach(entry -> {
HandlerWrapper<?> wrapper = entry.getValue();
try {
Object message = objectMapper.readValue(payload, wrapper.payloadType);
handleMessageSafely(wrapper, message,topic);
} catch (IOException e) {
if(logger.isDebugEnabled()){
logger.debug("反序列化失败 [主题: {}]", topic, e);
}
}
});
}
@SuppressWarnings("unchecked")
private <T> void handleMessageSafely(HandlerWrapper<?> wrapper, Object message, String topic) {
try {
T typedMessage = (T) wrapper.payloadType.cast(message);
((MqttMessageHandler<T>) wrapper.handler).handle(topic,typedMessage);
} catch (ClassCastException e) {
logger.error("类型转换失败 [预期类型: {}]", wrapper.payloadType.getName(), e);
}
}
private static class HandlerWrapper<T> {
final MqttMessageHandler<T> handler;
final Class<?> payloadType; // 修改为 Class<?>
final String originalTopic;
final int qos;
HandlerWrapper(MqttMessageHandler<T> handler,
Class<?> payloadType, // 修改为 Class<?>
String originalTopic,
int qos) {
this.handler = handler;
this.payloadType = payloadType;
this.originalTopic = originalTopic;
this.qos = qos;
}
}
// 获取所有需要订阅的主题
public List<String> getSubscribedTopics() {
return handlerMap.values().stream()
.map(wrapper -> wrapper.originalTopic)
.distinct()
.collect(Collectors.toList());
}
}
7. SpringBoot 自动注入
java
import org.eclipse.paho.client.mqttv3.*;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import java.util.UUID;
@Configuration
@ConditionalOnClass(MqttClient.class)
@ConditionalOnProperty(prefix = "mqtt", name = "broker")
@EnableConfigurationProperties(MqttProperties.class)
@Import(MqttHandlerRegistry.class)
public class MqttAutoConfiguration {
private final Logger logger = org.slf4j.LoggerFactory.getLogger(MqttAutoConfiguration.class);
private final MqttProperties properties;
public MqttAutoConfiguration(MqttProperties properties) {
this.properties = properties;
logger.info("MQTT 自动配置初始化,broker: {}", properties.getBroker());
}
@Bean
@ConditionalOnMissingBean
public EnhancedMqttFactory enhancedMQTTFactory(@Autowired(required = false) MqttCallback mqttCallback) {
logger.info("创建 EnhancedMQTTFactory 实例");
EnhancedMqttFactory.ReconnectConfig reconnectConfig = new EnhancedMqttFactory.ReconnectConfig()
.maxAttempts(properties.getReconnect().getMaxAttempts())
.initialDelay(properties.getReconnect().getInitialDelay())
.backoffFactor(properties.getReconnect().getBackoffFactor())
.autoRetryInitialConnect(properties.getReconnect().isAutoRetryInitialConnect());
EnhancedMqttFactory.Builder builder = new EnhancedMqttFactory.Builder(properties.getBroker())
.clientId(properties.getClientId() != null ? properties.getClientId() : UUID.randomUUID().toString())
.cleanSession(properties.isCleanSession())
.reconnectConfig(reconnectConfig);
if (properties.getUsername() != null && properties.getPassword() != null) {
logger.info("设置 MQTT 客户端认证信息");
builder.credentials(properties.getUsername(), properties.getPassword());
}
if (mqttCallback != null) {
logger.info("设置自定义 MQTT 回调");
builder.callback(mqttCallback);
}
return builder.build();
}
@Bean
@ConditionalOnMissingBean
public MqttClientWrapper mqttClientWrapper(
EnhancedMqttFactory factory,
MqttProperties properties,
MqttHandlerRegistry registry) throws Exception {
logger.info("创建 MQTT 客户端包装类实例");
MqttClientWrapper wrapper = factory.create();
// 自动订阅配置的 Topic
if (!properties.getTopics().isEmpty()) {
logger.info("自动订阅配置的主题: {}", properties.getTopics());
for (String topic : properties.getTopics()) {
wrapper.subscribe(topic);
}
}
// 自动订阅所有处理器关注的Topic
registry.getSubscribedTopics().forEach(topic -> {
try {
wrapper.subscribe(topic);
logger.info("自动订阅MQTT主题: {}", topic);
} catch (MqttException e) {
logger.error("订阅主题失败: {}", topic, e);
}
});
return wrapper;
}
@Bean
@ConditionalOnMissingBean
public MqttCallback defaultMqttCallback(MqttHandlerRegistry registry) {
logger.info("创建默认 MQTT 回调实例");
return new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
// 默认处理逻辑,例如日志记录
// logger.info("连接断开,建议在此实现重连逻辑");
}
@Override
public void messageArrived(String topic, MqttMessage message) {
// 默认处理逻辑
//mqttMessageHandlers
registry.processMessage(topic, message.getPayload());
// logger.info("收到消息 [主题: {} Qos: {}] 内容: {}", topic, message.getQos(), new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// 默认处理逻辑
// logger.info("消息投递完成: {} ", token.isComplete() ? "成功" : "失败");
}
};
}
}
三、Spring启动配置
yml
mqtt:
broker: tcp://127.0.0.1:1883
client-id: TestDemo
username: root
password: root
clean-session: true
reconnect:
initial-delay: 3000
backoff-factor: 2