话不多说,直接上代码
package org.example.imfutures.utils;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.eclipse.paho.client.mqttv3.*;
import org.example.imfutures.dto.CheckProperties;
import org.example.imfutures.dto.Properties;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
public class MQTTConnectUtils {
private final static String address = "SSL://你自己的mqtt服务器地址:8883";
MqttClient client;
/**
* 客户端连接华为云平台
* @param clientId
* @param password
* @param username
* @param callback
* @throws MqttException
*/
public void connect(String clientId, String password, String username, MqttCallback callback) throws MqttException {
client = new MqttClient(address, clientId);
MqttConnectOptions options = new MqttConnectOptions(); //连接参数设置
options.setCleanSession(true);
options.setUserName(username);
options.setPassword(password.toCharArray());
options.setAutomaticReconnect(true);
if (callback == null){
client.setCallback(new Callback());
}else {
client.setCallback(callback);
}
client.connect(options);
System.out.println("连接成功");
}
/**
* 订阅某一主题,此方法默认的的Qos等级为:1
* @param topic
* @throws MqttException
*/
public void subscribe(String topic) throws MqttException {
client.subscribe(topic, 0);
}
/**
* 向某一主题发送消息
* @param topic
* @param message
* @throws MqttException
*/
public void publish(String topic, String message) throws MqttException {
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setPayload(message.getBytes(StandardCharsets.UTF_8));
MqttTopic top = client.getTopic(topic);
MqttDeliveryToken token = top.publish(mqttMessage);
token.waitForCompletion();
}
/**
* 向某个主题发送对象类型的消息
* @param topic
* @param o
* @throws MqttException
*/
public void publish(String topic, Object o) throws MqttException {
MqttMessage message = new MqttMessage();
message.setPayload(o.toString().getBytes(StandardCharsets.UTF_8));
MqttTopic top = client.getTopic(topic);
MqttDeliveryToken token = top.publish(message);
token.waitForCompletion();
}
/**
* 向某个主题发送JSON类型消息
* @param topic
* @param o
* @throws MqttException
*/
public void publishJSON(String topic, Object o) throws MqttException {
MqttMessage message = new MqttMessage(); //封装要发布的消息
JsonObject json = new Gson().toJsonTree(o).getAsJsonObject(); //将对象转化为json对象
message.setPayload(json.toString().getBytes(StandardCharsets.UTF_8)); //设置消息内容为JSON字符串的字节数组,StandardCharsets.UTF_8:明确指定UTF-8编码
MqttTopic top = client.getTopic(topic); //获取要发布的主题
MqttDeliveryToken token = top.publish(message);
token.waitForCompletion(); //等待消息发布完成。这会阻塞当前线程,直到消息发布完成或超时
}
/**
* 向华为云lot平台某个设备某个主题发送JSON类型消息
* @param topic //主题
* @param o //属性对象
* @param serviceId //服务id
*/
public void publish(String topic, Object o, String serviceId) throws MqttException {
MqttMessage message = new MqttMessage();
JsonObject json = new Gson().toJsonTree(o).getAsJsonObject();
JsonObject service = new JsonObject();
service.addProperty("serviceId", serviceId);
service.addProperty("eventTime", formatIsoTime(new Timestamp(System.currentTimeMillis()))); //时间戳
service.add("properties", json);
JsonArray jsonArray = new JsonArray();
jsonArray.add(service);
JsonObject jsonObject = new JsonObject();
jsonObject.add("services", jsonArray);
message.setPayload(jsonObject.toString().getBytes(StandardCharsets.UTF_8));
MqttTopic top = client.getTopic(topic);
MqttDeliveryToken token = top.publish(message);
token.waitForCompletion();
}
/**
* 向华为云lot平台某一主题发送命令响应消息
* @param topic
* @throws MqttException
*/
public void publishCommand(String topic) throws MqttException {
MqttMessage message = new MqttMessage();
JsonObject json = new JsonObject();
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("result", "success");
json.addProperty("result_code", 0);
json.addProperty("response_name", "COMMAND_RESPONSE");
json.add("paras", jsonObject);
message.setPayload(json.toString().getBytes(StandardCharsets.UTF_8));
MqttTopic top = client.getTopic(topic);
MqttDeliveryToken token = top.publish(message);
token.waitForCompletion();
}
/**
* 关闭连接
*/
public void close() throws MqttException {
client.disconnect();
client.close();
}
/**
* ISO 8601时间格式化
* @param timestamp
* @return
*/
private String formatIsoTime(Timestamp timestamp) {
Instant instant = timestamp.toInstant();
return DateTimeFormatter.ISO_INSTANT.format(instant);
}
}
这段代码主要是用于华为云Lot平台连接,但也适用于其他使用mqtt协议的设备,是使用mqtt连接的主要部分。
接下来是回调函数Callback,在创建mqttclient实例对象时需要传入
package org.example.imfutures.utils;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
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;
import org.example.imfutures.dto.CheckProperties;
import org.example.imfutures.dto.Properties;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
/**
* 常规MQTT回调函数
*
* @author Mr.Qu
* @since 2020/1/9 16:26
*/
@Slf4j
public class Callback implements MqttCallback {
/**
* MQTT 断开连接会执行此方法
*/
@Override
public void connectionLost(Throwable throwable) {
log.error(throwable.getMessage(), throwable);*/
}
/**
* publish发布成功后会执行到这里
*/
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println("发布消息成功");
}
/**
* subscribe订阅后得到的消息会执行到这里
*/
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
// TODO 此处可以将订阅得到的消息进行业务处理、数据存储
System.out.println("收到来自 " + topic + " 的消息:" + new String(message.getPayload()));
}
}
业务逻辑主要是在messageArrived()方法里实现
需要的jar包是这些
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-core</artifactId>
<version>[3.0.40-rc, 3.2.0)</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-iotda</artifactId>
<version>[3.0.40-rc, 3.2.0)</version>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240303</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
这些代码都是直接复制粘贴即可使用
如果平台数据名称为中文,要使用对象发布消息时,要在实体类上使用@SerializedName()注解,例如