SpringBoot整合emqtt

一、emqtt安裝

使用rpm安裝emqtt並進行簡單的測試:以下是在虛擬機centos7下安裝的emqtt。
https://blog.csdn.net/lxw983520/article/details/89442373

二、相關配置

1. 在pom文件下添加以下maven依賴:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
        </dependency>

2. 在yml文件中進行mqtt的連接配置

  spring:
   mqtt:
    username: admin							# 賬號
    password: public						# 密碼
    host-url: tcp://ip:1883					# mqtt連接tcp地址
    client-id: test							# 客戶端Id,每個啓動的id要不同
    default-topic: test						# 默認主題
    timeout: 100							# 超時時間
    keepalive: 100							# 保持連接數

三、springboot-emqtt的整合

1. 獲取配置

package com.modules.common.mqtt;

import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @Classname MtqqEntity
 * @Description mqtt相關配置信息
 * @Date 2019/4/11 23:00
 * @Created by Jack
 */
@Component
@ConfigurationProperties("spring.mqtt")
@Setter
@Getter
public class MqttConfig {
    @Autowired
    private MqttPushClient mqttPushClient;

    /**
     * 用戶名
     */
    private String username;
    /**
     * 密碼
     */
    private String password;
    /**
     * 連接地址
     */
    private String hostUrl;
    /**
     * 客戶Id
     */
    private String clientId;
    /**
     * 默認連接話題
     */
    private String defaultTopic;
    /**
     * 超時時間
     */
    private int timeout;
    /**
     * 保持連接數
     */
    private int keepalive;

    @Bean
    public MqttPushClient getMqttPushClient() {
        mqttPushClient.connect(hostUrl, clientId, username, password, timeout, keepalive);
        // 以/#結尾表示訂閱所有以test開頭的主題
        mqttPushClient.subscribe("test/#", 0);
        return mqttPushClient;
    }
}

2. mqtt推送客戶端

package com.modules.common.mqtt;

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @Classname MqttPushClient
 * @Description mqtt推送客戶端
 * @Date 2019/4/11 23:22
 * @Created by Jack
 */
@Component
public class MqttPushClient {
    private static final Logger logger = LoggerFactory.getLogger(MqttPushClient.class);

    @Autowired
    private PushCallback pushCallback;

    private static MqttClient client;

    private static MqttClient getClient() {
        return client;
    }

    private static void setClient(MqttClient client) {
        MqttPushClient.client = client;
    }

    /**
     * 客戶端連接
     *
     * @param host      ip+端口
     * @param clientID  客戶端Id
     * @param username  用戶名
     * @param password  密碼
     * @param timeout   超時時間
     * @param keepalive 保留數
     */
    public void connect(String host, String clientID, String username, String password, int timeout, int keepalive) {
        MqttClient client;
        try {
            client = new MqttClient(host, clientID, new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setCleanSession(true);
            options.setUserName(username);
            options.setPassword(password.toCharArray());
            options.setConnectionTimeout(timeout);
            options.setKeepAliveInterval(keepalive);
            MqttPushClient.setClient(client);
            try {
                client.setCallback(pushCallback);
                client.connect(options);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 發佈
     *
     * @param qos         連接方式
     * @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 mTopic = MqttPushClient.getClient().getTopic(topic);
        if (null == mTopic) {
            logger.error("topic not exist");
        }
        MqttDeliveryToken token;
        try {
            token = mTopic.publish(message);
            token.waitForCompletion();
        } catch (MqttPersistenceException e) {
            e.printStackTrace();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    /**
     * 訂閱某個主題
     *
     * @param topic 主題
     * @param qos   連接方式
     */
    public void subscribe(String topic, int qos) {
        logger.info("開始訂閱主題" + topic);
        try {
            MqttPushClient.getClient().subscribe(topic, qos);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
}

3. 消費監聽類

package com.modules.common.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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Classname PushCallback
 * @Description 消費監聽類
 * @Date 2019/4/11 23:31
 * @Created by Jack
 */
@Component
public class PushCallback implements MqttCallback {
    private static final Logger logger = LoggerFactory.getLogger(MqttPushClient.class);

    @Autowired
    private MqttConfig mqttConfig;

    private static MqttClient client;

    @Override
    public void connectionLost(Throwable throwable) {
        // 連接丟失後,一般在這裏面進行重連
        logger.info("連接斷開,可以做重連");
        if (null != client) {
            mqttConfig.getMqttPushClient();
        }
    }

    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        // subscribe後得到的消息會執行到這裏面
        logger.info("接收消息主題 : " + topic);
        logger.info("接收消息Qos : " + mqttMessage.getQos());
        logger.info("接收消息內容 : " + new String(mqttMessage.getPayload()));
    }

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

4. 測試服務

package com.test.controller;

import com.modules.common.exception.ExceptionUtils;
import com.modules.common.mqtt.MqttPushClient;
import com.modules.common.utils.RUtils;
import com.modules.common.validator.ValidatorUtils;
import com.test.entity.TestUser;
import com.test.form.TestForm;
import com.test.service.TestService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * @author: lxw
 * @Date: 2018/10/19 19:36
 * @email: [email protected]
 * @Description: 測試文件
 */
@RestController
@RequestMapping("/")
@Api("測試")
public class TestController {
 
    @Autowired
    private MqttPushClient mqttPushClient;

    @ApiOperation(value = "發佈主題", notes = "測試發佈主題")
    @GetMapping(value = "/publishTopic")
    public RUtils publishTopic() {
        mqttPushClient.publish(0,false,"test/test","測試一下發布消息");
        return RUtils.ok();
    }
}

三、測試成果

  1. 進入後臺訂閱“test/test”主題,注意要進行連接
    連接
  2. 接口發送相關信息。
    發送信息
  3. 後臺接收到相應的信息。
    接收消息
    此時項目中的客戶端也訂閱了test/下的主題,因此也會收到相應的消息。
    獲取數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章