java連接MQTT服務器(Springboot整合MQTT)

目錄

一、業務場景

二、本文只講解java連接MQTT服務器進行數據處理


一、業務場景

 硬件採集的數據傳入EMQX平臺(採用MQTT協議),java通過代碼連接MQTT服務器,進行採集數據接收、解析、業務處理、存儲入庫、數據展示。

MQTT 是基於 發佈(Publish)/訂閱(Subscribe) 模式來進行通信及數據交換的。

二、本文只講解java連接MQTT服務器進行數據處理

1、新建springboot項目,pom文件中直接引入下面的mqtt依賴

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

2、 編寫MQTT工具類

package com.siborui.dc.mqtt;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * MQTT工具類操作
 *
 * @author Mr.Qu
 * @since v1.1.0 2020-01-10
 */
@Slf4j
@Component
public class MQTTConnect {

    private String HOST = "tcp://127.0.0.1:1883"; //mqtt服務器的地址和端口號
    private final String clientId = "DC" + (int) (Math.random() * 100000000);
    private MqttClient mqttClient;

    /**
     * 客戶端connect連接mqtt服務器
     *
     * @param userName     用戶名
     * @param passWord     密碼
     * @param mqttCallback 回調函數
     **/
    public void setMqttClient(String userName, String passWord, MqttCallback mqttCallback) throws MqttException {
        MqttConnectOptions options = mqttConnectOptions(userName, passWord);
        if (mqttCallback == null) {
            mqttClient.setCallback(new Callback());
        } else {
            mqttClient.setCallback(mqttCallback);
        }
        mqttClient.connect(options);
    }

    /**
     * MQTT連接參數設置
     */
    private MqttConnectOptions mqttConnectOptions(String userName, String passWord) throws MqttException {
        mqttClient = new MqttClient(HOST, clientId, new MemoryPersistence());
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(userName);
        options.setPassword(passWord.toCharArray());
        options.setConnectionTimeout(10);///默認:30
        options.setAutomaticReconnect(true);//默認:false
        options.setCleanSession(false);//默認:true
        //options.setKeepAliveInterval(20);//默認:60
        return options;
    }

    /**
     * 關閉MQTT連接
     */
    public void close() throws MqttException {
        mqttClient.close();
        mqttClient.disconnect();
    }

    /**
     * 向某個主題發佈消息 默認qos:1
     *
     * @param topic:發佈的主題
     * @param msg:發佈的消息
     */
    public void pub(String topic, String msg) throws MqttException {
        MqttMessage mqttMessage = new MqttMessage();
        //mqttMessage.setQos(2);
        mqttMessage.setPayload(msg.getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(topic);
        MqttDeliveryToken token = mqttTopic.publish(mqttMessage);
        token.waitForCompletion();
    }

    /**
     * 向某個主題發佈消息
     *
     * @param topic: 發佈的主題
     * @param msg:   發佈的消息
     * @param qos:   消息質量    Qos:0、1、2
     */
    public void pub(String topic, String msg, int qos) throws MqttException {
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setQos(qos);
        mqttMessage.setPayload(msg.getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(topic);
        MqttDeliveryToken token = mqttTopic.publish(mqttMessage);
        token.waitForCompletion();
    }

    /**
     * 訂閱某一個主題 ,此方法默認的的Qos等級爲:1
     *
     * @param topic 主題
     */
    public void sub(String topic) throws MqttException {
        mqttClient.subscribe(topic);
    }

    /**
     * 訂閱某一個主題,可攜帶Qos
     *
     * @param topic 所要訂閱的主題
     * @param qos   消息質量:0、1、2
     */
    public void sub(String topic, int qos) throws MqttException {
        mqttClient.subscribe(topic, qos);
    }

    /**
     * main函數自己測試用
     */
    public static void main(String[] args) throws MqttException {
        MQTTConnect mqttConnect = new MQTTConnect();
        mqttConnect.setMqttClient("admin", "public", new Callback());
        mqttConnect.pub("com/iot/init", "Mr.Qu" + (int) (Math.random() * 100000000));
        mqttConnect.sub("com/iot/init");
    }
}

3、編寫MQTT的回調函數

package com.siborui.dc.mqtt;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;

/**
 * 常規MQTT回調函數
 *
 * @author Mr.Qu
 * @since 2020/1/9 16:26
 */
@Slf4j
public class Callback implements MqttCallback {

    /**
     * MQTT 斷開連接會執行此方法
     */
    @Override
    public void connectionLost(Throwable throwable) {
        log.info("斷開了MQTT連接 :{}", throwable.getMessage());
        log.error(throwable.getMessage(), throwable);
    }

    /**
     * publish發佈成功後會執行到這裏
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        log.info("發佈消息成功");
    }

    /**
     * subscribe訂閱後得到的消息會執行到這裏
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        //  TODO    此處可以將訂閱得到的消息進行業務處理、數據存儲
        log.info("收到來自 " + topic + " 的消息:{}", new String(message.getPayload()));
    }
}

4、由於業務場景需要,在項目啓動時,監聽MQTT主題Topic,編寫MQTT監聽器

package com.siborui.dc.mqtt;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import com.siborui.dc.mqtt.Callback;

/**
 * 項目啓動 監聽主題
 *
 * @author Mr.Qu
 * @since 2020/1/10
 */
@Slf4j
@Component
public class MQTTListener implements ApplicationListener<ContextRefreshedEvent> {

    private final MQTTConnect server;

    @Autowired
    public MQTTListener(MQTTConnect server) {
        this.server = server;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        try {
            server.setMqttClient("admin", "public", new Callback());
            server.sub("com/iot/init");
        } catch (MqttException e) {
            log.error(e.getMessage(), e);
        }
    }
}


5、不明白之處請留言,感覺有用的  給個打賞

感謝大佬

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章