提交 a1114be6 编写于 作者: 如梦技术's avatar 如梦技术 🐛

📝 梳理更新记录。

上级 b60c1d1d
......@@ -4,7 +4,8 @@
### v2.0.1 - 2022-09-10
- :sparkles: 优化 MqttWebServer 配置。
- :bug: 修复解码异常: BufferUnderflowException。
- :sparkles: mica-mqtt-example 添加华为云iot连接示例。
- :bug: 修复解码异常: `BufferUnderflowException`
### v2.0.0 - 2022-09-04
- :sparkles: mica mqtt server 完善方法,方便使用。
......
/*
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.net.dreamlu.net).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.dreamlu.iot.mqtt.huawei;
import net.dreamlu.iot.mqtt.codec.ByteBufferUtil;
import net.dreamlu.iot.mqtt.core.client.MqttClient;
import java.nio.charset.StandardCharsets;
import java.util.Timer;
import java.util.TimerTask;
/**
* 客户端测试
*
* @author L.cm
*/
public class MqttClientTest {
public static void main(String[] args) {
// 设备id和密钥,请从华为云iot获取
String deviceId = "630eb6f8664c6f7938db6ef0_test";
String deviceSecret = "";
// 计算MQTT连接参数。
MqttSign sign = new MqttSign(deviceId, deviceSecret);
String username = sign.getUsername();
String password = sign.getPassword();
String clientId = sign.getClientId();
System.out.println("username: " + username);
System.out.println("password: " + password);
System.out.println("clientid: " + clientId);
// 初始化 mqtt 客户端
MqttClient client = MqttClient.create()
.ip("iot-mqtts.cn-north-4.myhuaweicloud.com")
.port(8883)
.username(username)
.password(password)
.clientId(clientId)
.useSsl()
.connect();
// 订阅命令下发topic
String cmdRequestTopic = "$oc/devices/" + deviceId + "/sys/commands/#";
client.subQos0(cmdRequestTopic, (topic, payload) -> {
System.out.println(topic + '\t' + ByteBufferUtil.toString(payload));
});
// 属性上报消息
String reportTopic = "$oc/devices/" + deviceId + "/sys/properties/report";
String jsonMsg = "{\"services\":[{\"service_id\":\"Temperature\", \"properties\":{\"value\":57}},{\"service_id\":\"Battery\",\"properties\":{\"level\":88}}]}";
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
client.publish(reportTopic, jsonMsg.getBytes(StandardCharsets.UTF_8));
}
}, 3000, 3000);
}
}
/*
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.net.dreamlu.net).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.dreamlu.iot.mqtt.huawei;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
/**
* 阿里云 mqtt 签名方式
*
* @author L.cm
*/
public class MqttSign {
/**
* 用户名
*/
private final String username;
/**
* 密码
*/
private final String password;
/**
* 客户端id
*/
private final String clientId;
public MqttSign(String deviceId, String deviceSecret) {
Objects.requireNonNull(deviceId, "deviceId is null");
Objects.requireNonNull(deviceSecret, "deviceSecret is null");
this.username = deviceId;
String timestamp = getTimeStamp();
this.password = getPassword(deviceSecret, timestamp);
this.clientId = getClientId(deviceId, timestamp);
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getClientId() {
return clientId;
}
private static String getPassword(String deviceSecret, String timestamp) {
return hmacSha256(deviceSecret, timestamp);
}
private static String getClientId(String deviceId, String timestamp) {
return deviceId + "_0_0_" + timestamp;
}
/***
* 要求:10位数字
*/
private static String getTimeStamp() {
return ZonedDateTime.ofInstant(Instant.now(), ZoneId.of("UTC")).format(DateTimeFormatter.ofPattern("yyyyMMddHH"));
}
/***
* 调用sha256算法进行哈希
*/
private static String hmacSha256(String message, String tStamp) {
try {
Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
hmacSHA256.init(new SecretKeySpec(tStamp.getBytes(), "HmacSHA256"));
byte[] bytes = hmacSHA256.doFinal(message.getBytes());
return byteArrayToHexString(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/***
* byte数组转16进制字符串
*/
private static String byteArrayToHexString(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b != null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1) {
hs.append('0');
}
hs.append(stmp);
}
return hs.toString().toLowerCase();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册