spring boot mqtt开发-原生 Paho 手动封装(最高灵活性,完全自定义)

文章目录

Mqtt的java开发,归纳起来包含如下5种方式:

方法类型 封装程度 开发效率 灵活性 企业级特性 适用场景
原生 Paho 手动封装 极高 无(需自研)
Spring Integration MQTT (集成流) 中大型项目、Spring 集成生态
spring-boot-starter-mqtt 极高 小型项目、快速原型开发
cn.herodotus.stirrup 极高 极高 (重连 / 重试 / 连接池) 企业级项目、高可靠需求
emqx-spring-boot-starter 通用企业级项目、EMQ 生态

本文主要是采用第一种,原生方式。原生 Paho 手动封装(最高灵活性,完全自定义)

核心优势

  • 无第三方依赖,仅依赖 Paho 核心包;
  • 完全自定义连接、订阅、回调逻辑,无封装层限制;
  • 资源占用极低,适配嵌入式 / 轻量场景。

废话不多说,看代码,步骤。


一、pom.xml依赖

b 复制代码
<!-- 仅引入 Paho MQTT 核心依赖(无任何封装) -->
<dependency>
    <groupId>org.eclipse.paho</groupId>
    <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
    <version>1.2.5</version>
</dependency>

二、yml文件配置

b 复制代码
mqtt:
  broker: tcp://localhost:1883
  clientId: paho-client-${random.value}
  username: admin
  password: public
  qos: 1

三、配置类

创建配置类,初始化 MQTT 客户端并自动订阅配置的主题,无需手动启动,Spring Boot 启动时自动加载:

b 复制代码
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PahoMqttConfig {
    private static final Logger log = LoggerFactory.getLogger(PahoMqttConfig.class);

    // 从配置文件读取参数
    @Value("${mqtt.broker:tcp://localhost:1883}")
    private String broker;
    @Value("${mqtt.clientId:paho-client-${random.value}}")
    private String clientId;
    @Value("${mqtt.username:admin}")
    private String username;
    @Value("${mqtt.password:public}")
    private String password;
    @Value("${mqtt.qos:1}")
    private int qos;

    /**
     * 手动创建 MQTT 客户端(核心)
     */
    @Bean
    public MqttClient mqttClient() {
        try {
            // 1. 创建连接配置
            MqttConnectOptions options = new MqttConnectOptions();
            options.setUserName(username);
            options.setPassword(password.toCharArray());
            options.setCleanSession(true); // 断开后清除会话
            options.setConnectionTimeout(30); // 连接超时
            options.setKeepAliveInterval(60); // 心跳间隔
            options.setAutomaticReconnect(true); // 开启自动重连(Paho 原生特性)

            // 2. 创建客户端(内存持久化,避免文件IO)
            MqttClient client = new MqttClient(broker, clientId, new MemoryPersistence());
            // 3. 设置消息回调(处理收到的消息)
            client.setCallback(new CustomMqttCallback());
            // 4. 连接服务器
            client.connect(options);
            log.info("原生 Paho MQTT 客户端连接成功 → broker: {}", broker);

            // 5. 订阅主题(可订阅多个)
            client.subscribe("sensor/temp", qos);
            client.subscribe("test/paho/#", qos);
            log.info("原生 Paho 订阅主题成功");

            return client;
        } catch (MqttException e) {
            log.error("原生 Paho MQTT 客户端初始化失败", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 消息发送工具类(封装发布逻辑)
     */
    @Bean
    public MqttMessageSender mqttMessageSender() {
        return new MqttMessageSender(mqttClient(), qos);
    }
}

四、消息处理类

创建消息监听类,重写消息接收方法,所有订阅主题的消息都会走到这里,可根据主题区分处理:

b 复制代码
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Paho 原生消息回调(必须实现 MqttCallback 接口)
 */
public class CustomMqttCallback implements MqttCallback {
    private static final Logger log = LoggerFactory.getLogger(CustomMqttCallback.class);

    // 收到消息时触发(核心方法)
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        String content = new String(message.getPayload(), "UTF-8");
        log.info("原生 Paho 收到消息 → 主题:{},QoS:{},内容:{}",
                topic, message.getQos(), content);
        // 业务逻辑处理...
    }

    // 连接断开时触发(可自定义重连逻辑)
    @Override
    public void connectionLost(Throwable cause) {
        log.error("原生 Paho MQTT 连接断开", cause);
    }

    // 消息发布完成时触发(发布者用)
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        // 空实现(订阅者无需处理)
    }
}

五、消息发送工具类

b 复制代码
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 封装消息发送逻辑
 */
public class MqttMessageSender {
    private static final Logger log = LoggerFactory.getLogger(MqttMessageSender.class);
    private final MqttClient client;
    private final int qos;

    public MqttMessageSender(MqttClient client, int qos) {
        this.client = client;
        this.qos = qos;
    }

    /**
     * 发送 MQTT 消息
     */
    public void send(String topic, String content) {
        try {
            MqttMessage message = new MqttMessage(content.getBytes("UTF-8"));
            message.setQos(qos);
            message.setRetained(false); // 不保留消息
            client.publish(topic, message);
            log.info("原生 Paho 发送消息成功 → 主题:{},内容:{}", topic, content);
        } catch (Exception e) {
            log.error("原生 Paho 发送消息失败", e);
        }
    }
}

六、测试

b 复制代码
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class PahoTestController {
    @Resource
    private MqttMessageSender mqttMessageSender;

    @GetMapping("/paho/send")
    public String sendMsg(@RequestParam String topic, @RequestParam String content) {
        mqttMessageSender.send(topic, content);
        return "原生 Paho 消息发送成功!";
    }
}
相关推荐
sunnyday04262 小时前
Filter、Interceptor、Spring AOP 的执行顺序详解
java·spring boot·后端·spring
想用offer打牌2 小时前
一站式了解Spring AI Alibaba的Memory机制
java·人工智能·后端·spring·chatgpt·系统架构
打工的小王2 小时前
Langchain4j(二)RAG知识库
java·后端·ai·语言模型
李慕婉学姐2 小时前
【开题答辩过程】以《基于springcloud的空气质量监控管理系统》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
后端·spring·spring cloud
Remember_9932 小时前
【数据结构】Java对象比较全解析:从equals到Comparable与Comparator,再到PriorityQueue应用
java·开发语言·数据结构·算法·leetcode·哈希算法
沛沛老爹2 小时前
从Web到AI:多模态Agent Skills生态系统实战(Java+Vue构建跨模态智能体)
java·前端·vue.js·人工智能·rag·企业转型
a努力。3 小时前
饿了么Java面试被问:一致性哈希的虚拟节点和数据迁移
java·chrome·后端·websocket·面试·职场和发展
把csdn当日记本的菜鸡3 小时前
Java设计模式简单入门
java·开发语言·设计模式