SpringBoot集成MQTT

927 阅读2分钟

1、MQTT服务器环境准备:

由于工作中有用到MQTT,所以不用搭建MQTT服务器,但是那是生产环境,不能随便搞,所以,只能白嫖。 点击这里试用14天。这个链接点进去,点击免费试用,按指引来,就能一键部署一个MQTT服务器,足够学习使用。然后下载MQTT客户端MQTTX点击这里,就可以下载,然后简单看一下怎么使用,就可以先连接着玩一玩。

2、项目搭建:

2.1、目录结构:

image.png

2.2、依赖配置:

plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    maven { url "https://maven.aliyun.com/nexus/content/groups/public"}
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web:2.4.2'
    implementation 'org.springframework.integration:spring-integration-mqtt:5.3.2.RELEASE'
}

2.3、yml配置:

mqtt:
  username: test
  password: test123
  url: tcp://59.110.140.97:1883
  clientId: ${random.value}

2.4、yml配置对应的实体

@Component
@ConfigurationProperties(prefix = "mqtt")
public class MqttProperties {
    private String url;
    private String username;
    private String password;
    private String clientId;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }
}

2.5、消费者客户端配置:

@Configuration
// 开启对Spring-Integration组件的扫描
@IntegrationComponentScan
/**
 * mqtt消费端配置
 */
public class MqttConsumerConfiguration {

    @Resource
    private MqttProperties mqttProperties;

    @Resource
    private MqttInboundHandler mqttInboundHandler;

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

    @Bean
    public MqttPahoClientFactory mqttPahoClientFactory(){
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setServerURIs(new String[]{mqttProperties.getUrl()});
        mqttConnectOptions.setUserName(mqttProperties.getUsername());
        mqttConnectOptions.setPassword(mqttProperties.getPassword().toCharArray());
        // 客户端连接服务端超时时间
        mqttConnectOptions.setConnectionTimeout(10);
        // 从消息发送到消息接收的时间间隔,超过视为断连
        mqttConnectOptions.setKeepAliveInterval(90);
        // 断连是是否清除会话
        mqttConnectOptions.setCleanSession(true);
        // 断线重连
        mqttConnectOptions.setAutomaticReconnect(true);
        DefaultMqttPahoClientFactory clientFactory = new DefaultMqttPahoClientFactory();
        clientFactory.setConnectionOptions(mqttConnectOptions);
        return clientFactory;
    }

    @Bean
    public MessageProducer inbound(MqttPahoClientFactory mqttPahoClientFactory){
        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(
                mqttProperties.getClientId(), mqttPahoClientFactory, "hello/#");
        /**
         * By default, the default DefaultPahoMessageConverter produces a message with a String payload with the following headers:
         *  mqtt_topic: The topic from which the message was received
         *  mqtt_duplicate: true if the message is a duplicate
         *  mqtt_qos: The quality of service
         */
        adapter.setConverter(new DefaultPahoMessageConverter());
        // 服务质量:0:至多一次;1:至少一次;2:正好一次
        adapter.setQos(1);
        adapter.setOutputChannel(inputChannel());
        return adapter;
    }

    @Bean
    /**
     * ServiceActivator是用于将服务实例连接到消息传递系统的通用端点。必须配置输入消息通道,如果要调用的服务方法能够返回值,还可以提供输出消息通道
     */
    @ServiceActivator(inputChannel = "inputChannel")
    public MessageHandler inBoundHandler(){
        return mqttInboundHandler;
    }
}

2.6、消费消息的方法:

@Component
public class MqttInboundHandler implements MessageHandler {
    @Override
    public void handleMessage(Message<?> message) throws MessagingException {
        System.out.println(message.getPayload());
    }
}

2.7、生产者客户端的配置:

@Configuration
@IntegrationComponentScan
/**
 * mqtt生产端配置
 */
public class MqttProducerConfiguration {

    @Resource
    private MqttProperties mqttProperties;

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

    @Bean
    @ServiceActivator(inputChannel = "outPutChannel")
    public MessageHandler outBound(MqttPahoClientFactory mqttPahoClientFactory){
        MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler(mqttProperties.getClientId(), mqttPahoClientFactory);
        mqttPahoMessageHandler.setAsync(true);
        return mqttPahoMessageHandler;
    }
}

2.8、生产者生产消息的方法:

@Component
@MessagingGateway(defaultRequestChannel = "outPutChannel")
public interface MqttGateWay {
    void sendToMqtt(String payload,@Header(MqttHeaders.TOPIC) String topic);
}

2.9、调用生产者进行消息发送:

@RestController
@RequestMapping("/say")
public class ProductMqttMessageController {
    @Resource
    private MqttGateWay mqttGateWay;

    @GetMapping("/hello/{message}")
    public void sendMqttMessage(@PathVariable("message") String message){
        mqttGateWay.sendToMqtt(message,"hello");
    }
}

3、运行效果

首先,我们可以在IDEA里对这个demo启动两个实例,方法如下:

3.1、第一个实例:

image.png

3.2、第二个实例:

image.png image.png 然后分别启动: image.png 选择要启动的应用,然后点击右侧运行的绿三角即可启动两个应用。

4、访问:

例如可以访问:http://localhost:8081/say/hello/mqtt1, 可以看到后台打印出了接收到的消息。

5、GitHub地址:点击获取SpringBoot集成MQTT