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

相关推荐
Hx_Ma162 分钟前
SSM搭建(三)Spring整合SpringMVC框架
java·后端·spring
无风听海4 分钟前
.NET10之ASP.NET Core的Filter管线
java·asp.net·.net
静听山水4 分钟前
StarRocks高级特性
数据库
少许极端5 分钟前
算法奇妙屋(二十八)-递归、回溯与剪枝的综合问题 1
java·算法·深度优先·剪枝·回溯·递归
Boop_wu7 分钟前
简单介绍 JSON
java·开发语言
范纹杉想快点毕业10 分钟前
从单片机基础到程序框架:全方位技术深度解析
数据库·mongodb
晚风_END12 分钟前
Linux|操作系统|elasticdump的二进制方式部署
运维·服务器·开发语言·数据库·jenkins·数据库开发·数据库架构
devmoon13 分钟前
Polkadot SDK 自定义 Pallet Benchmark 指南:生成并接入 Weight
开发语言·网络·数据库·web3·区块链·波卡
知识即是力量ol13 分钟前
初识 Kafka(一):分布式流平台的定义、核心优势与架构全景
java·分布式·kafka·消息队列
爱吃生蚝的于勒17 分钟前
【Linux】线程概念(一)
java·linux·运维·服务器·开发语言·数据结构·vim