springboot集成mqtt,并通过mqttMessageListener实现多线程订阅

<!--集成MQTT-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-stream</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-mqtt</artifactId>
</dependency>
package com.fuel.core.mqtt;

import com.fuel.common.constant.MqttConstants;
import com.fuel.common.core.redis.RedisCache;
import com.fuel.common.utils.StringUtils;
import com.fuel.common.utils.ip.IpUtils;
import com.fuel.common.utils.spring.SpringUtils;
import com.fuel.equipment.domain.FuelDevice;
import com.fuel.equipment.service.IFuelDeviceService;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.List;


@Configuration
public class MqttConsumer {
    private static final Logger logger = LoggerFactory.getLogger(MqttConsumer.class);
    @Autowired
    private MqttMessageListener mqttMessageListener;
    @Autowired
    private IFuelDeviceService fuelDeviceService;
    @Value("${aliMqtt.username}")
    private String username;
    @Value("${aliMqtt.password}")
    private String password;
    @Value("${aliMqtt.hostUrl}")
    private String hostUrl;
    @Value("${aliMqtt.clientId}")
    private String clientId;

    /**
     * 客户端对象
     */
    private MqttClient client;


    /**
     * 在bean初始化后连接到服务器
     */
    @PostConstruct
    public void init(){
        connect();
    }


    /**
     * 客户端连接服务端
     */
    public void connect(){
        try {
            //创建MQTT客户端对象
            MqttClient mqttClient = new MqttClient(hostUrl, clientId + System.currentTimeMillis() + "_" + IpUtils.getHostIp(), new MemoryPersistence());
            client = mqttClient;

            //设置回调
            client.setCallback(new MqttConsumerCallBack());
            //连接设置
            MqttConnectOptions options = new MqttConnectOptions();
            //是否清空session,设置为false表示服务器会保留客户端的连接记录,客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
            //设置为true表示每次连接到服务端都是以新的身份
            options.setCleanSession(true);
            options.setAutomaticReconnect(true);// 自动重连
            //设置连接用户名
//            options.setUserName(username);
            //设置连接密码
//            options.setPassword(password.toCharArray());
            //设置超时时间,单位为秒
            options.setConnectionTimeout(100);
            //设置心跳时间 单位为秒,表示服务器每隔1.5*20秒的时间向客户端发送心跳判断客户端是否在线
            options.setKeepAliveInterval(20);
//            client.connect(options);
            IMqttToken iMqttToken = client.connectWithResult(options);
            boolean complete = iMqttToken.isComplete();
            logger.info("MQTT连接"+(complete?"成功":"失败"));
            RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
            List<FuelDevice> fuelDevicesList = redisCache.getCacheObject(MqttConstants.MQTT_PUBLIC_KEY + "fuel_devices_list");
            if (StringUtils.isEmpty(fuelDevicesList)) {
                fuelDevicesList = fuelDeviceService.selectDeviceListByMqtt(new FuelDevice());
                redisCache.setCacheObject(MqttConstants.MQTT_PUBLIC_KEY + "fuel_devices_list", fuelDevicesList);
            }
            if(StringUtils.isNotEmpty(fuelDevicesList)){
                for(FuelDevice fuelDevice : fuelDevicesList){
                    String mqttDeviceName = fuelDevice.getMqttDeviceName();
                    String format = String.format(MqttConstants.MQTT_PREFIX, mqttDeviceName);
                    if(StringUtils.isNotEmpty(mqttDeviceName)){
                        String[] topics = {format + MqttConstants.MQTT_IS_ONLINE, //在线状态
                                format + MqttConstants.MQTT_SENSOR, //传感器数据
                                format + MqttConstants.MQTT_OILCAN, //实时油罐数据
                                format + MqttConstants.MQTT_TANK_TABLE, // 罐表数据
                                format + MqttConstants.MQTT_TANK_SET, //油罐数据
//                                format + MqttConstants.MQTT_POST_ALARM, //实时报警数据
                                format + MqttConstants.MQTT_ALARM, //报警记录
                                format + MqttConstants.MQTT_UNLOAD_OIL //卸油记录
                        };
                        for(int i = 0; i < topics.length; i++){
                            client.subscribe(topics[i], 1, mqttMessageListener);
                        }
                    }
                }
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }


    /**
     * 断开连接
     */
    public void disConnect(){
        try {
            client.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }



    /**
     * 订阅主题
     */
    public void subscribe(String topic){
        try {
            client.subscribe(topic, 1, mqttMessageListener);
        } catch (MqttException e) {
            e.printStackTrace();
            connect();
        }
    }

    public void subscribe(String topic[]){
        try {
            client.subscribe(topic);
        } catch (MqttException e) {
            e.printStackTrace();
            connect();
        }
    }

    /**
     * 取消订阅主题
     *
     * @param topic 主题名称
     */
    public void cleanTopic(String topic) {
        if (client != null && client.isConnected()) {
            try {
                client.unsubscribe(topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("取消订阅失败!");
        }
    }

    /**
     * 批量取消订阅主题
     *
     * @param topic 主题名称
     */
    public void cleanTopic(String topic[]) {
        if (client != null && client.isConnected()) {
            try {
                client.unsubscribe(topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("取消订阅失败!");
        }
    }

    /**
     * 发布
     *
     * @param qos         连接方式
     * @param retained    是否保留
     * @param topic       主题
     * @param pushMessage 消息体
     */
    public void publish(int qos, boolean retained, String[] topic, String pushMessage) {
        MqttMessage message = new MqttMessage();
        message.setQos(qos);
        message.setRetained(retained);
        message.setPayload(pushMessage.getBytes());
        for(int i = 0; i < topic.length; i++){
            MqttTopic mTopic = client.getTopic(topic[i]);
            if (null == mTopic) {
                logger.error("topic not exist");
            }
            MqttDeliveryToken token;
            try {
                token = mTopic.publish(message);
                token.waitForCompletion();
            } catch (MqttException e) {
                e.printStackTrace();
                connect();
            }
        }
    }

    public void publish(int qos, boolean retained, String topic, String pushMessage) {
        MqttMessage message = new MqttMessage();
        message.setQos(qos);
        message.setRetained(retained);
        message.setPayload(pushMessage.getBytes());
        MqttTopic mTopic = client.getTopic(topic);
        if (null == mTopic) {
            logger.error("topic not exist");
        }
        MqttDeliveryToken token;
        try {
            token = mTopic.publish(message);
            token.waitForCompletion();
        } catch (MqttPersistenceException e) {
            e.printStackTrace();
            connect();
        } catch (MqttException e) {
            e.printStackTrace();
            connect();
        }
    }
}
package com.fuel.core.mqtt;

import cn.hutool.core.util.CharsetUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fuel.admin.service.ISysConfigService;
import com.fuel.common.constant.MqttConstants;
import com.fuel.common.core.redis.RedisCache;
import com.fuel.common.utils.DateUtils;
import com.fuel.common.utils.StringUtils;
import com.fuel.common.utils.spring.SpringUtils;
import com.fuel.equipment.service.IFuelDeviceService;
import com.fuel.equipment.service.ITankCapacityService;
import com.fuel.framework.manager.AsyncManager;
import com.fuel.mqttData.service.*;
import lombok.SneakyThrows;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

@Component
public class MqttMessageListener implements IMqttMessageListener {
    private static final Logger logger = LoggerFactory.getLogger(MqttMessageListener.class);

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {

        AsyncManager.me().execute(recordOper(topic, message));
    }

    public static TimerTask recordOper(String topic, MqttMessage message)
    {
        return new TimerTask()
        {

            @SneakyThrows
            public void run()
            {
               
            }
        };
    }
}

Spring Boot 集成 MQTT 订阅接收多个 topic 的基本步骤如下: 1. 添加依赖:首先需要在 Spring Boot 项目的 pom.xml 文件中添加 MQTT 客户端库的依赖。常用的库有 Eclipse Paho MQTT Java Client。比如添加如下依赖: ```xml <dependency> <groupId>org.eclipse.paho</groupId> <artifactId>org.eclipse.paho.client.mqttv3</artifactId> <version>1.2.5</version> </dependency> ``` 2. 配置 MQTT 连接属性:通过配置文件(比如 application.properties 或 application.yml)定义 MQTT 服务器连接的相关属性,如服务器地址、端口、用户名、密码等。 ```properties # application.properties 示例 mqtt.url=tcp://broker.hivemq.com:1883 mqtt.username=user mqtt.password=password ``` 3. 配置 MQTT 客户端:创建一个配置类,使用 `@Configuration` 注解标记。通过 `@Bean` 注解创建配置 `MqttConnectOptions` 和 `MqttPahoClientFactory`。这样 Spring Boot 容器会自动配置 MQTT 客户端,且可以根据需要自动注入。 ```java @Configuration public class MqttConfig { @Value("${mqtt.url}") private String url; @Value("${mqtt.username}") private String username; @Value("${mqtt.password}") private String password; @Bean public MqttConnectOptions mqttConnectOptions() { MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); mqttConnectOptions.setServerURIs(new String[]{url}); mqttConnectOptions.setUserName(username); mqttConnectOptions.setPassword(password.toCharArray()); return mqttConnectOptions; } @Bean public MqttPahoClientFactory mqttClientFactory() { DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory(); factory.setConnectionOptions(mqttConnectOptions()); return factory; } } ``` 4. 实现消息监听器:创建一个类实现 `MqttMessageListener` 接口或使用 `@MqttMessageSubscriber` 注解,定义消息接收的方法,然后订阅需要接收消息的 topic。 ```java @Service public class MqttReceiver implements MqttMessageListener { @Override @MqttMessageSubscriber(topic = "topic1") public void processMessage(String data) { // 处理接收到的消息 } @Override @MqttMessageSubscriber(topic = "topic2") public void processMessage(String data) { // 处理接收到的消息 } } ``` 通过以上步骤,Spring Boot 应用就能够集成 MQTT 订阅多个 topic 接收消息了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wengelovelian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值