springboot+mqtt初体验

MQTT(消息队列遥测传输)是ISO标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议。国内很多企业都广泛使用MQTT作为Android手机客户端与服务器端推送消息的协议。

springboot集成mqtt简单demo测试,后续还需深入理解应用。

依赖

        <!--增加mqtt依赖,注意版本冲突问题-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
            <!--<version>2.3.0.RELEASE</version>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-stream</artifactId>
            <!--<version>5.2.1.RELEASE</version>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
            <!--<version>5.2.1.RELEASE</version>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

properties配置

spring.mqtt.username=admin
spring.mqtt.password=public
#EMQX服务的tcp协议端口默认为1883
spring.mqtt.url=tcp://127.0.0.1:1883
spring.mqtt.default.topic=topic1
spring.mqtt.client.id=clientId-001
spring.mqtt.consumer.clientId=consumerClientId-001
spring.mqtt.consumer.defaultTopic=topic1

部分代码如下:

@Configuration
@IntegrationComponentScan
public class MqttConfig {

    private static final Logger logger = LoggerFactory.getLogger(MqttConfig.class);

    @Value("${spring.mqtt.username}")
    private String username;

    @Value("${spring.mqtt.password}")
    private String password;

    @Value("${spring.mqtt.url}")
    private String hostUrl;

    @Value("${spring.mqtt.client.id}")
    private String clientId;

    @Value("${spring.mqtt.default.topic}")
    private String defaultTopic;

    @Value("${spring.mqtt.consumer.clientId}")
    private String consumerClientId;

    @Value("${spring.mqtt.consumer.defaultTopic}")
    private String consumerDefaultTopic;

    //入站通道名(消费者)订阅的bean名称
    public static final String CHANNEL_NAME_IN = "mqttInboundChannel";
    //出站通道名(生产者)发布的bean名称
    public static final String CHANNEL_NAME_OUT = "mqttOutboundChannel";

    /**
     * MQTT连接器选项
     *
     * @return {@link org.eclipse.paho.client.mqttv3.MqttConnectOptions}
     */
    @Bean
    public MqttConnectOptions getMqttConnectOptions() {
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setUserName(username);
        mqttConnectOptions.setPassword(password.toCharArray());
        mqttConnectOptions.setServerURIs(new String[]{hostUrl});
        mqttConnectOptions.setKeepAliveInterval(2);
        return mqttConnectOptions;
    }

    /**
     * MQTT客户端
     *
     * @return {@link org.springframework.integration.mqtt.core.MqttPahoClientFactory}
     */
    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(getMqttConnectOptions());
        return factory;
    }

    /*******************************生产者*******************************************/

    /**
     * MQTT信息通道(生产者)
     *
     * @return {@link org.springframework.messaging.MessageChannel}
     */
    @Bean(name = CHANNEL_NAME_OUT)
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }

    /**
     * MQTT消息处理器(生产者)
     *
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(clientId, mqttClientFactory());
        messageHandler.setAsync(true);
        messageHandler.setDefaultTopic(defaultTopic);
        return messageHandler;
    }

    /*******************************消费者*******************************************/

    /**
     * MQTT信息通道(消费者)
     *
     * @return {@link org.springframework.messaging.MessageChannel}
     */
    @Bean(name = CHANNEL_NAME_IN)
    public MessageChannel mqttInboundChannel() {
        return new DirectChannel();
    }

    /**
     * MQTT消息订阅绑定(消费者)
     *
     * @return {@link org.springframework.integration.core.MessageProducer}
     */
    @Bean
    public MessageProducer inbound() {
        // 可以同时消费(订阅)多个Topic
        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(consumerClientId, mqttClientFactory(), consumerDefaultTopic);
        adapter.setCompletionTimeout(5000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
        // 设置订阅通道
        adapter.setOutputChannel(mqttInboundChannel());
        return adapter;
    }

    /**
     * MQTT消息处理器(消费者)
     *
     * @return {@link org.springframework.messaging.MessageHandler}
     */
    @Bean
    @ServiceActivator(inputChannel = CHANNEL_NAME_IN)
    public MessageHandler handler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString();
                String msg = message.getPayload().toString();
                logger.info("接收到订阅消息:\ntopic:" + topic + "\nmessage:" + msg);
            }
        };
        //or 调用MqttMessageConsumer类处理收到的消息
        //return new MqttMessageConsumer();
    }

}
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
@Component
public interface MqttMessageProducer {

    /**
     * payload或者data是发送消息的内容
     * topic是消息发送的主题,这里可以自己灵活定义,也可以使用默认的主题,就是配置文件的主题,qos是mqtt 对消息处理的几种机制分为0,1,2 其中0表示的是订阅者没收到消息不会再次发送,消息会丢失,1表示的是会尝试重试,一直到接收到消息,但这种情况可能导致订阅者收到多次重复消息,2相比多了一次去重的动作,确保订阅者收到的消息有一次
     * 当然,这三种模式下的性能肯定也不一样,qos=0是最好的,2是最差的
     */

    void sendToMqtt(String data);

    void sendToMqtt(String payload, @Header(MqttHeaders.TOPIC) String topic);

    void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
}
@Component
public class MqttMessageConsumer implements MessageHandler {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void handleMessage(Message<?> message) throws MessagingException {
        String topic = String.valueOf(message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC));
        String payload = String.valueOf(message.getPayload());
        logger.info("接收到 mqtt消息,主题:{} 消息:{}", topic, payload);
    }
}

结果:

接收到订阅消息:
topic:topic1
message:111

EMQX服务监控信息如上。

Spring Boot 是一个用于创建独立、基于 Spring 的应用程序的框架,它简化了 Spring 的配置和部署过程。MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布订阅模式的消息传输协议,广泛应用于物联网领域。WebSocket是一种全双工通信协议,可以在浏览器和服务器之间建立持久性的连接。 在Spring Boot中,可以通过整合 Spring Integration 和 Eclipse Paho(MQTT Java 客户端)来实现 MQTT 推送。首先,需要将 Paho MQTT 依赖添加到项目的 Maven 或 Gradle 构建文件中。然后,通过编写相应的 Java 代码,在 Spring Boot 中配置 MQTT 的连接和订阅信息。可以使用 @EnableMqtt 注解来启用 MQTT 功能,并通过配置文件指定 MQTT 的连接参数和订阅主题。最后,使用 @MqttListener 注解定义一个消息监听器,用于接收和处理 MQTT 推送的消息。 而要实现 WebSocket 的推送功能,可以通过整合 Spring WebSocket 和 Spring Security 实现。首先,在 Spring Boot 中配置 WebSocket 的端点,并编写相应的处理器类来处理 WebSocket 的连接和消息。可以使用 @EnableWebSocket 和 @Configuration 注解启用 WebSocket 功能,并将自定义的 WebSocketConfig 类添加到 Spring Boot 的配置中。接着,使用 @Component 注解将 WebSocket 处理器类注册为 Spring 的 Bean。最后,通过编写前端代码,在浏览器中建立 WebSocket 连接,并发送和接收消息。 综上所述,通过整合 Spring Boot、MQTT 和 WebSocket 技术,可以实现 MQTT 和 WebSocket 的推送功能。可以通过配置文件和编写相应的 Java 和前端代码来完成相应的配置和接口开发。这样就可以实现在 Spring Boot 应用中利用 MQTT 和 WebSocket 实现消息的推送和接收。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值