mqtt - spring-integration-mqtt

使用 spring 插件的好处是:提供了很多标准实现,比如重连机制,服务断线的时候,会自动重连。

缺点就是,如果不满意 spring 的设计,想改一点东西,也挺麻烦的。

Maven 依赖

<dependency>
	<groupId>org.springframework.integration</groupId>
	<artifactId>spring-integration-mqtt</artifactId>
	<version>5.2.11.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.eclipse.paho</groupId>
	<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
	<version>1.2.5</version>
</dependency>

MQTT 配置


import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

/**
 * 消息处理器
 *
 * @author Mr.css
 * @version 2024-10-15 17:20
 */
@Configuration
@IntegrationComponentScan
public class MqttClientConfig {

    // 消费端的 客户ID
    private static final String IN_CLIENT_ID = "MQTTReceiver";
    // 生产端的 客户ID
    private static final String OUT_CLIENT_ID = "MqttPublish";

    /**
     * 连接工厂,配置账号密码等信息
     */
    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();

        // mqtt-v3
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName("dev");
        options.setPassword("dev".toCharArray());
        options.setServerURIs(new String[]{"tcp://localhost:1883"});

        // 心跳包间隔,10s - 60s
        options.setKeepAliveInterval(MqttConnectOptions.KEEP_ALIVE_INTERVAL_DEFAULT);
        // 连接超时配置
        options.setConnectionTimeout(MqttConnectOptions.CONNECTION_TIMEOUT_DEFAULT);

        // 自动重连
        options.setAutomaticReconnect(true);

        factory.setConnectionOptions(options);
        return factory;
    }

    // inbound -----------------------------------------------------------------------------------

    /**
     * 消息侦听回调
     */
    @Bean
    public MqttCallback inbound() {
        String[] topics = {"mqtt"};
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(IN_CLIENT_ID, mqttClientFactory(), topics);

        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.initialize();

        // 线程池
        adapter.setTaskScheduler(scheduler);

        // 消息转换器
        adapter.setConverter(new DefaultPahoMessageConverter());
        // 注释写操作超时,不知道具体指什么操作,先默认。应该是连接时候的超时,跟消息消费时间没关系
        adapter.setCompletionTimeout(MqttPahoMessageDrivenChannelAdapter.DEFAULT_COMPLETION_TIMEOUT);

        adapter.setQos(2);
        adapter.setOutputChannel(mqttInputChannel());
        return adapter;
    }

    /**
     * 注意函数名称,对应于 {@link ServiceActivator#inputChannel()}
     *
     * @return 消息通道
     */
    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }

    /**
     * 消息处理
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")
    public MessageHandler handler() {
        return (message -> {
            Object topic = message.getHeaders().get("mqtt_receivedTopic");
            String payload = message.getPayload().toString();
            System.out.println("消息主题:" + topic);
            System.out.println("消息内容:" + payload);
        });
    }

    // outbound ----------------------------------------------------------------------------------

    /**
     * 注意函数名称,对应于 {@link ServiceActivator#outputChannel()}
     *
     * @return 消息通道
     */
    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }

    /**
     * 消息发布
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttOutboundChannel")
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler =
                new MqttPahoMessageHandler(OUT_CLIENT_ID, mqttClientFactory());
        messageHandler.setAsync(true);
        messageHandler.setDefaultQos(2);
        messageHandler.setDefaultRetained(false);
        return messageHandler;
    }

}


消息发送

这是一个接口,与 @Repository 类似,虽然没有实现类,但是可以直接调用

import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

/**
 * 消息发送接口
 *
 * @author Mr.css
 * @version 2024-10-15 17:30
 */
@Component
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface MqttGateway {

    void send(@Header(MqttHeaders.TOPIC) String topic, String data);
}

posted on   疯狂的妞妞  阅读(88)  评论(0编辑  收藏  举报

(评论功能已被禁用)
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2020-10-31 poi - word合并单元格,拖动之后还原问题
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示