【应用】SpringBoot 整合 MQTT

MQTT 消息生产者

创建 maven 项目 provider9001

依赖、配置文件以及主启动类

首先引入 MQTT 相关依赖

        <!--mqtt相关依赖-->
        <dependency>
            <groupId>org.eclipse.paho</groupId>
            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
            <version>1.2.5</version>
        </dependency>

在配置文件中定义 MQTT 客户端的基本配置

spring:
  application:
    name: provider
  #MQTT配置信息
  mqtt:
    #MQTT服务端地址,端口默认为11883,如果有多个,用逗号隔开
    url: tcp://<Your_MQTT-SERVER_IP>:11883
    #用户名
    username: admin
    #密码
    password: public
    #客户端id(不能重复)
    client:
      id: provider_id
    #MQTT默认的消息推送主题,实际可在调用接口时指定
    default:
      topic: test
server:
  port: 9001

配置项目主启动类

@SpringBootApplication
public class Provider9001 {

    public static void main(String[] args) {
        SpringApplication.run(Provider9001.class);
    }

}

MQTT 生产者客户端

编写 MQTT 客户端,进行客户端的初始化以及与服务器的连接,编写推送消息的方法

@Component
public class MqttProviderClient {

    @Value("${spring.mqtt.username}")
    private String username;
    @Value("${spring.mqtt.password}")
    private String password;
    @Value("${spring.mqtt.url}")
    private String hostUrl;
    @Value("${spring.mqtt.client.id}")
    private String clientId;
    @Value("${spring.mqtt.default.topic}")
    private String defaultTopic;

    private MqttClient mqttClient;

    /**
     * 初始化生产者客户端
     */
    @PostConstruct
    public void init() {
        connect();
    }

    /**
     * 客户端连接服务端
     */
    public void connect(){
        try {
            // 初始化客户端
            mqttClient = new MqttClient(hostUrl, clientId, new MemoryPersistence());

            // 配置客户端连接参数
            MqttConnectOptions options = new MqttConnectOptions();
            //是否清空session,设置false表示服务器会保留客户端的连接记录(订阅主题,qos),客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
            //设置为true表示每次连接服务器都是以新的身份
            options.setCleanSession(true);
            // 配置用户名和密码
            options.setUserName(username);
            options.setPassword(password.toCharArray());
            // 设置超时时间,单位为秒
            options.setConnectionTimeout(100);
            // 设置心跳时间 单位为秒,表示服务器每隔 1.5*20秒的时间向客户端发送心跳判断客户端是否在线
            options.setKeepAliveInterval(20);
            // 设置遗嘱消息的话题,若客户端和服务器之间的连接意外断开,服务器将发布客户端的遗嘱信息
            options.setWill("willTopic", (clientId + "与服务器断开连接").getBytes(), 0, false);
            // 配置回调
            mqttClient.setCallback(new MqttProviderCallback());
            // 执行连接
            mqttClient.connect(options);
        } catch (MqttException e) {
            e.printStackTrace();
        }

    }

    /**
     * 客户端消息发送
     * @param qos qos
     * @param retained retained
     * @param topic topic
     * @param message message
     */
    public void publish(int qos,boolean retained,String topic,String message){
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setQos(qos);
        mqttMessage.setRetained(retained);
        mqttMessage.setPayload(message.getBytes());
        // 主题的目的地,用于发布/订阅信息
        MqttTopic mqttTopic = mqttClient.getTopic(topic);
        // 提供一种机制来跟踪消息的传递进度
        // 用于在以非阻塞方式(在后台运行)执行发布是跟踪消息的传递进度
        MqttDeliveryToken token;
        try {
            // 将指定消息发布到主题,但不等待消息传递完成,返回的token可用于跟踪消息的传递状态
            // 一旦此方法干净地返回,消息就已被客户端接受发布,当连接可用,将在后台完成消息传递
            token = mqttTopic.publish(mqttMessage);
            token.waitForCompletion();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
}

MQTT 生产者客户端回调类

配置各种情况下客户端的处理逻辑

@Slf4j
@Component
public class MqttProviderCallback implements MqttCallback {

    @Value("${spring.mqtt.client.id}")
    private String clientId;

    /**
     * 断开连接回调
     */
    @Override
    public void connectionLost(Throwable throwable) {
        log.error(clientId + "与服务器断开连接...");
    }

    /**
     * 消息送达回调
     */
    @Override
    public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
        log.info("信息已送达...");
    }

    /**
     * 发送成功回调
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        IMqttAsyncClient client = iMqttDeliveryToken.getClient();
        log.info(client.getClientId() + "发布消息成功...");
    }
}

控制类

@RestController
@RequestMapping("/mqtt/provider")
public class MqttProviderController {

    @Resource
    MqttProviderClient mqttProviderClient;

    /**
     * 发送消息
     * @param qos qos
     * @param retained retained
     * @param topic topic
     * @param message message
     * @return 发送结果
     */
    @GetMapping("/sendMessage")
    public String sendMessage(int qos, boolean retained, String topic, String message){
        try {
            mqttProviderClient.publish(qos, retained, topic, message);
            return "发送成功";
        } catch (Exception e) {
            e.printStackTrace();
            return "发送失败";
        }
    }

}

MQTT 消息消费者

创建 maven 项目 consumer9002

依赖、配置文件以及主启动类

依赖同生产者,配置文件修改如下

spring:
  application:
    name: consumer
  #MQTT配置信息
  mqtt:
    #MQTT服务端地址,端口默认为11883,如果有多个,用逗号隔开
    url: tcp://<Your_MQTT-SERVER_IP>:11883
    #用户名
    username: admin
    #密码
    password: public
    #客户端id(不能重复)
    client:
      id: consumer_id
    #MQTT默认的消息推送主题,实际可在调用接口时指定
    default:
      topic: test
server:
  port: 9002

MQTT 消费者客户端

进行客户端的初始化以及与服务器的连接,并配置订阅的主题以及 QoS

@Component
public class MqttConsumerClient {

    @Value("${spring.mqtt.username}")
    private String username;
    @Value("${spring.mqtt.password}")
    private String password;
    @Value("${spring.mqtt.url}")
    private String hostUrl;
    @Value("${spring.mqtt.client.id}")
    private String clientId;
    @Value("${spring.mqtt.default.topic}")
    private String defaultTopic;

    /**
     * mqtt 客户端
     */
    private MqttClient mqttClient;

    /**
     * 初始化客户端
     */
    @PostConstruct
    public void init() {
        // 初始化逻辑
        connect();
    }

    /**
     * 初始化客户端连接服务器
     */
    public void connect() {
        try {
            // 创建服务器连接
            mqttClient = new MqttClient(hostUrl, clientId, new MemoryPersistence());

            // 配置连接参数
            MqttConnectOptions options = new MqttConnectOptions();
            // 是否清空session,设置为false表示服务器会保留客户端的连接记录,客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
            // 设置为true表示每次连接到服务端都是以新的身份
            options.setCleanSession(true);
            // 配置用户名和密码
            options.setUserName(username);
            options.setPassword(password.toCharArray());
            // 设置超时时间,单位为秒
            options.setConnectionTimeout(100);
            // 设置心跳时间 单位为秒,表示服务器每隔1.5*20秒的时间向客户端发送心跳判断客户端是否在线
            options.setKeepAliveInterval(20);
            // 设置遗嘱消息的话题,若客户端和服务器之间的连接意外断开,服务器将发布客户端的遗嘱信息
            options.setWill("willTopic", (clientId + "与服务器断开连接").getBytes(), 0, false);
            // 设置回调
            mqttClient.setCallback(new MqttConsumerCallback());
            // 执行连接
            mqttClient.connect(options);

            // 配置订阅主题
            int[] qos = {1, 1, 1};
            String[] topics = {"test", "test1", "test2"};
            // 执行订阅
            mqttClient.subscribe(topics, qos);
        }  catch (MqttException e) {
            e.printStackTrace();
        }
    }

    /**
     * 服务端断开连接
     */
    public void disConnect() {
        try {
            mqttClient.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

}

MQTT 消费者客户端回调类

配置各种情况的回调处理逻辑

@Slf4j
@Component
public class MqttConsumerCallback implements MqttCallback {

    @Value("${spring.mqtt.client.id}")
    private String clientId;

    /**
     * 断开连接回调
     */
    @Override
    public void connectionLost(Throwable throwable) {
        log.error(clientId + "与服务器断开连接...");
    }

    /**
     * 监听消息回调
     */
    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        log.info("接收消息主题:{}", topic);
        log.info("接收消息Qos:{}", mqttMessage.getQos());
        log.info("接收消息内容:{}", new String(mqttMessage.getPayload()));
        log.info("接收消息retained:{}", mqttMessage.isRetained());
    }

    /**
     * 发送消息完成回调
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

    }
}

控制类

@RestController
@RequestMapping("/mqtt/consumer")
public class MqttConsumerController {

    @Resource
    private MqttConsumerClient mqttConsumerClient;

    @Value("${spring.mqtt.client.id}")
    private String clientId;

    @RequestMapping("/connect")
    public String connect(){
        mqttConsumerClient.connect();
        return clientId + "连接到服务器";
    }

    @RequestMapping("/disConnect")
    public String disConnect(){
        mqttConsumerClient.disConnect();
        return clientId + "与服务器断开连接";
    }

}

MQTT 测试使用

启动 EMQX 服务器,登录 dashboard(端口号 18083,初始账号密码见配置文件)
在这里插入图片描述

分别启动 MQTT 生产者客户端和消费者客户端,查看 dashboard 是否成功连接至服务器
在这里插入图片描述

调用生产者发送消息接口,发送消息
在这里插入图片描述

查看消费者监听窗口,获取消息
在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值