mqtt springboot整合emqx

2,343 阅读2分钟

准备:

1.安装emqx

免费下载、试用 EMQ 产品 (emqx.com)

docker快速安装

docker run --restart=always -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.0.11

2.pom依赖

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-mqtt</artifactId>
    <version>5.5.13</version>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-stream</artifactId>
    <version>5.5.13</version>
</dependency>

3.yml文件

mqtt:
  open: true
  #MQTT-服务器连接地址,如果有多个,用逗号隔开
  host: tcp://192.168.20.3:1883
  #MQTT-连接服务器默认客户端ID
  clientId: mqtt_id
  #MQTT-用户名
  username: admin
  #MQTT-密码
  password: admin
  #MQTT-默认的消息推送主题,实际可在调用接口时指定
  topic: test
  #连接超时
  timeout: 1000
  #设置会话心跳时间
  keepalive: 100

springboot步骤

1.MqttConfig配置类,初始化客户端

//MQTT订阅
@Slf4j
@Configuration
@ConfigurationProperties("mqtt")
@Data
@Component
public class MqttConfig {

    String host;
    String clientId;
    String topic;
    String username;
    String password;
    Integer timeout;
    Integer keepalive;

    @Bean
    @ConditionalOnProperty(prefix = "mqtt",name="open",havingValue = "true")
    public MqttConnectOptions mqttConnectOptions() {
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        options.setCleanSession(true);
        options.setConnectionTimeout(timeout);
        options.setKeepAliveInterval(keepalive);
        return options;
    }

    @Bean
    @ConditionalOnProperty(prefix = "mqtt",name="open",havingValue = "true")

    public MqttClient mqttClient(MqttConnectOptions mqttConnectOptions) {
        try {
            MqttClient client = new MqttClient(host, clientId);

            client.setCallback(new MessageCallback());
            IMqttToken iMqttToken = client.connectWithResult(mqttConnectOptions);
            boolean complete = iMqttToken.isComplete();
            log.info("mqtt建立连接:{}", complete);

            // 订阅主题
            client.subscribe(topic, 0);
            log.info("已订阅topic:{}", topic);

            return client;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("mqtt 连接异常");
        }
    }
}
    

2.mqtt回调,用于接收消息

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.stereotype.Component;

/**
 * consumer 消费者
 */
@Component
@Slf4j
public class MessageCallback implements MqttCallback {

    @Autowired(required = false)
    private  MqttClient client;

    @Override
    public void connectionLost(Throwable throwable) {
        if (client == null || !client.isConnected()) {
            log.info("连接断开,正在重连....");
            try {
                client.connect();
                if(client.isConnected()){
                    log.info("mqtt重连完成.");
                }
            } catch (MqttException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        log.info("接收消息主题 : " + topic);
        log.info("接收消息内容 : " + new String(message.getPayload()));
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        log.info("deliveryComplete---------" + token.isComplete());
    }
}

3.mqtt工具类

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class MqttUtil {

    @Autowired(required = false)
    private MqttClient client;

    /**
     * 订阅主题
     * @param topic
     * @param qos
     */
    public void subscribe(String topic, int qos) {
        try {
            client.subscribe(topic, qos);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    /**
     * 订阅主题
     * @param topic
     */
    public void subscribe(String topic) {
        try {
            client.subscribe(topic);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    /**
     * 发布消息
     *
     * @param qos         连接方式 0,1,2 默认0
     *
     * @param retained    是否保留最新的消息
     * @param topic       订阅主题
     * @param pushMessage 消息体
     */
    public void publish(int qos, boolean retained, String topic, String pushMessage) {
        MqttMessage message = new MqttMessage();
        message.setQos(qos);
        message.setRetained(retained);
        message.setPayload(pushMessage.getBytes());
        MqttTopic mqttTopic = client.getTopic(topic);
        if (null == mqttTopic) {
            log.error("topic not exist");
        }
        MqttDeliveryToken token;
        try {
            token = mqttTopic.publish(message);
            token.waitForCompletion();
        } catch (MqttPersistenceException e) {
            e.printStackTrace();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发布消息
     * @param topic 主题
     * @param pushMessage 消息内容
     */
    public void publish( String topic, String pushMessage) {
        publish(0,true,topic,pushMessage);

    }
}

4.测试

4.1 连接成功判断

image.png

4.2.发送消息

@RestController
@Slf4j
public class MqttController {

    @Autowired
    MqttClient client;

    @Autowired
    MqttUtil mqttUtil;

    @GetMapping("/send")
    public String send() {
        try {

            for (int i = 0; i < 3; i++) {
                mqttUtil.publish("test","消息hello"+i);
                log.info("发送成功:{}", i);
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "SUCCESS";
    }
}