目錄
一、業務場景
硬件採集的數據傳入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、不明白之處請留言,感覺有用的 給個打賞