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

相关推荐
bbq粉刷匠5 小时前
从0开始学java--day6.5
java
HitpointNetSuite5 小时前
连锁餐饮行业ERP如何选择:为何Oracle NetSuite成为增长新引擎
大数据·运维·数据库·oracle·netsuite
冻咸鱼6 小时前
MySQL基础知识大全
数据库·mysql·oracle
emma羊羊6 小时前
【Redis】
数据库·redis·缓存
lang201509286 小时前
Spring Boot构建RESTful服务与Actuator监控
spring boot·后端·restful
Slow菜鸟7 小时前
SpringBoot集成Elasticsearch | Elasticsearch 8.x专属Java Client
java·spring boot·elasticsearch
Miraitowa_cheems7 小时前
LeetCode算法日记 - Day 82: 环形子数组的最大和
java·数据结构·算法·leetcode·决策树·线性回归·深度优先
豐儀麟阁贵8 小时前
4.5数组排序算法
java·开发语言·数据结构·算法·排序算法
Halo_tjn8 小时前
Java Map集合
java·开发语言·计算机