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()
            {
               
            }
        };
    }
}

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot 是一个用于快速构建 Spring 应用程序的框架,而 MQTT 是一种轻量级的消息传递协议。将 Spring BootMQTT 集成可以让我们更加容易地创建一个可靠的、实时的通信系统。以下是如何将 Spring Boot 集成 MQTT 发布/订阅的步骤: 1. 引入 MQTT 相关依赖:在 pom.xml 文件中添加以下依赖: <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-mqtt</artifactId> <version>1.1.3.RELEASE</version> </dependency> 2. 配置 MQTT:在 application.properties 文件中添加以下配置: # MQTT 配置 mqtt.client.id=spring-boot-mqtt mqtt.username=username mqtt.password=password mqtt.url=tcp://localhost:1883 3. 编写发布代码:使用 Spring Integration 的 PublishSubscribeChannel 和 MqttPahoMessageHandler 来向 MQTT 发布消息。 @Autowired private MessageChannel mqttOutboundChannel; public void sendToMqtt(String message) { mqttOutboundChannel.send(MessageBuilder.withPayload(message).build()); } 4. 编写订阅代码:使用 Spring Integration 的 MqttPahoMessageDrivenChannelAdapter 和 MessageHandler 来实现订阅。 @Bean public MessageChannel mqttInputChannel() { return new DirectChannel(); } @Bean public MqttPahoMessageDrivenChannelAdapter mqttInbound() { String clientId = MqttAsyncClient.generateClientId(); MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(mqtt.url, clientId, mqtt.topic); adapter.setCompletionTimeout(5000); adapter.setConverter(new DefaultPahoMessageConverter()); adapter.setQos(1); adapter.setOutputChannel(mqttInputChannel()); return adapter; } @Bean @ServiceActivator(inputChannel = "mqttInputChannel") public MessageHandler handler() { return message -> { String payload = message.getPayload().toString(); System.out.println("MQTT Received: " + payload); }; } 通过以上步骤,我们可以轻松地集成 MQTT 发布/订阅功能。注意,在实际的应用程序中,我们需要为 MQTT 客户端定义一个独特的客户端 ID,并在订阅消息时指定选择的 MQTT 主题。这可以确保不同的客户端能够接收到正确的消息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wengelovelian

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

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

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

打赏作者

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

抵扣说明:

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

余额充值