[小白]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即可

相关推荐
Joy T5 小时前
Agent 确定性上下文设计:从 Prompt 参数注入到能力分层
java·开发语言·微服务·架构·prompt·agent context
AIgorithmGEEK8 小时前
MySQL 索引全解(下):建、查、删实战与知识速查表
数据库·mysql·b+树·索引
m0_587383008 小时前
广州 24 小时自助健身房解决方案技术实现与实战指南
java·spring·小程序·架构·需求分析
·云扬·9 小时前
Prompt 工程与安全:从 System 设计到注入防御
java·人工智能·安全·ai·prompt
代码不停10 小时前
自动化测试(java)
java·开发语言·selenium·自动化
唠点键盘之外的10 小时前
26 向量数据库实战:从 0 搭一条能用的检索链路(pgvector + Spring AI)
数据库·人工智能·spring
云和恩墨11 小时前
数据库监控简史:监控不止于告警——从图表大爆发到健康管理闭环
数据库
ly768911 小时前
MongoDB 事务开销实测:快照隔离下的写冲突、重试与分片事务边界
数据库·mongodb·事务·分片集群·快照隔离·写冲突
豆角焖肉11 小时前
Spring AOP 自定义注解实现系统操作日志
数据库·自定义注解·springaop·操作日志·aop 切面
鬼手点金12 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github