[小白]spring boot接入emqx

每次接都要搜索好久。

JDK 11 和 Spring Boot 2.7.7 的版本信息, EMQX 5.8.8

安装EMQX 5.8.8

复制代码
docker pull emqx/emqx:5.8.8

docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.8.8

http://localhost:18083

默认用户名及密码(此处用户名密码是登录的用户名和密码,与后面的连接时的用户名和密码不同):

admin

public

添加依赖

在 pom.xml 中添加以下依赖,确保版本与 Spring Boot 2.7.7 兼容:

复制代码
<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.7.7</version>
    </dependency>
    
    <!-- Spring Integration MQTT -->
    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-mqtt</artifactId>
        <version>5.5.15</version> <!-- 与 Spring Boot 2.7.7 兼容 -->
    </dependency>
    
    <!-- Eclipse Paho MQTT 客户端 -->
    <dependency>
        <groupId>org.eclipse.paho</groupId>
        <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
        <version>1.2.5</version>
    </dependency>
</dependencies>

配置 application.yml

在 src/main/resources/application.yml 中配置 EMQX 连接参数。EMQX 5.8.8 默认监听 1883 端口(MQTT TCP)。假设本地运行,匿名认证(生产环境请配置用户名/密码)

复制代码
mqtt:
  broker: tcp://localhost:1883
  client-id: spring-boot-client-${random.uuid}
  username: admin
  password: admin
  default-topic: test/topic
  qos: 1
  keepalive: 60
  connection-timeout: 5000
  clean-session: true

配置 MQTT 客户端

创建 MqttConfig.java,配置 Spring Integration 的 MQTT 入站和出站适配器:

复制代码
package com.example.config;

import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;

@Configuration
public class MqttConfig {

    @Value("${mqtt.broker}")
    private String brokerUrl;

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

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

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

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

    @Value("${mqtt.qos}")
    private int qos;

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        MqttConnectOptions options = new MqttConnectOptions();
        options.setServerURIs(new String[]{brokerUrl});
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        options.setKeepAliveInterval(60);
        options.setConnectionTimeout(5000);
        options.setCleanSession(true);
        factory.setConnectionOptions(options);
        return factory;
    }

    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MqttPahoMessageDrivenChannelAdapter inbound(MqttPahoClientFactory mqttClientFactory) {
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(clientId + "-inbound", mqttClientFactory, defaultTopic);
        adapter.setCompletionTimeout(5000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(qos);
        adapter.setOutputChannel(mqttInputChannel());
        return adapter;
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")
    public MessageHandler handler() {
        return message -> {
            String payload = (String) message.getPayload();
            String topic = (String) message.getHeaders().get("mqtt_receivedTopic");
            System.out.println("接收到 MQTT 消息: 主题=" + topic + ", 内容=" + payload);
        };
    }

    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttOutboundChannel")
    public MqttPahoMessageHandler mqttOutbound(MqttPahoClientFactory mqttClientFactory) {
        MqttPahoMessageHandler messageHandler =
                new MqttPahoMessageHandler(clientId + "-outbound", mqttClientFactory);
        messageHandler.setAsync(true);
        messageHandler.setDefaultTopic(defaultTopic);
        messageHandler.setDefaultQos(qos);
        return messageHandler;
    }
}

关于订阅主题以下代码可订阅多个

复制代码
MqttPahoMessageDrivenChannelAdapter adapter =
        new MqttPahoMessageDrivenChannelAdapter(clientId + "-inbound", mqttClientFactory, "test/topic", "sensor/#", "device/+");

#:匹配多级主题,如 sensor/data/temp。

+:匹配单级主题,如 device/123。

如需订阅所有主题 ,可以直接用#,如下代码

复制代码
MqttPahoMessageDrivenChannelAdapter adapter =
        new MqttPahoMessageDrivenChannelAdapter(clientId + "-inbound", mqttClientFactory, "test/topic", "#");

发布消息服务

创建 MqttService.java 用于发送消息:

复制代码
package com.example.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

@Service
public class MqttService {

    @Autowired
    private MessageChannel mqttOutboundChannel;

    public void publish(String topic, String payload) {
        mqttOutboundChannel.send(
                MessageBuilder.withPayload(payload)
                        .setHeader("mqtt_topic", topic)
                        .build()
        );
        System.out.println("已发布消息到主题 " + topic + ": " + payload);
    }
}

测试 Controller

创建 MqttController.java 用于 REST 接口测试:

复制代码
package com.example.controller;

import com.example.service.MqttService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MqttController {

    @Autowired
    private MqttService mqttService;

    @GetMapping("/publish")
    public String publish(@RequestParam String message) {
        mqttService.publish("test/topic", message);
        return "消息已发送: " + message;
    }
}

测试

订阅:应用启动后自动订阅 test/topic,发送消息到该主题会在控制台打印。

发布:访问 http://localhost:8080/publish?message=Hello EMQX!,用 MQTTX 或 EMQX Dashboard 验证消息。

MQTT桌面客户端软件使用 MQTTX即可

相关推荐
一氧化二氢.h1 分钟前
MySQL root用户连接错误解决方法
android·数据库·mysql
q***57504 分钟前
微服务搭建----springboot接入Nacos2.x
spring boot·微服务·架构
Chan169 分钟前
【 Java八股文面试 | JVM篇 内存结构、类加载、垃圾回收与性能调优 】
java·jvm·spring boot·后端·spring·idea
q***239215 分钟前
数据库操作与数据管理——Rust 与 SQLite 的集成
数据库·rust·sqlite
q***333719 分钟前
给SQL server数据库表字段添加注释SQL,附修改、删除注释SQL及演示
数据库·sql·oracle
北执南念27 分钟前
企业级 Spring Boot + WebSocket + Redis 分布式消息推送方案
spring boot·redis·websocket
百锦再29 分钟前
第15章 并发编程
android·java·开发语言·python·rust·django·go
百***221230 分钟前
mysql 迁移达梦数据库出现的 sql 语法问题 以及迁移方案
数据库·sql·mysql
_Jimmy_32 分钟前
ShardingSphere-JDBC 实现两个mysql数据库的不同表的关联查询
数据库·mysql
weixin_307779131 小时前
基于AWS的应用程序可靠性提升架构优化方案——RDS多可用区与EC2弹性架构实践
数据库·数据仓库·架构·云计算·aws