fix:【IoT 物联网】code review tcp 实现
This commit is contained in:
@@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// TODO @haohao:这种写成单测,会好点
|
||||
/**
|
||||
* TCP二进制格式数据包示例
|
||||
*
|
||||
@@ -21,13 +22,13 @@ public class TcpBinaryDataPacketExamples {
|
||||
|
||||
public static void main(String[] args) {
|
||||
IotTcpBinaryDeviceMessageCodec codec = new IotTcpBinaryDeviceMessageCodec();
|
||||
|
||||
|
||||
// 1. 数据上报包示例
|
||||
demonstrateDataReport(codec);
|
||||
|
||||
|
||||
// 2. 心跳包示例
|
||||
demonstrateHeartbeat(codec);
|
||||
|
||||
|
||||
// 3. 复杂数据上报示例
|
||||
demonstrateComplexDataReport(codec);
|
||||
}
|
||||
@@ -37,23 +38,23 @@ public class TcpBinaryDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateDataReport(IotTcpBinaryDeviceMessageCodec codec) {
|
||||
log.info("=== 二进制格式数据上报包示例 ===");
|
||||
|
||||
|
||||
// 创建传感器数据
|
||||
Map<String, Object> sensorData = new HashMap<>();
|
||||
sensorData.put("temperature", 25.5);
|
||||
sensorData.put("humidity", 60.2);
|
||||
sensorData.put("pressure", 1013.25);
|
||||
sensorData.put("battery", 85);
|
||||
|
||||
|
||||
// 创建设备消息
|
||||
IotDeviceMessage message = IotDeviceMessage.requestOf("thing.property.post", sensorData);
|
||||
message.setDeviceId(123456L);
|
||||
|
||||
|
||||
// 编码
|
||||
byte[] packet = codec.encode(message);
|
||||
log.info("编码后数据包长度: {} 字节", packet.length);
|
||||
log.info("编码后数据包(HEX): {}", bytesToHex(packet));
|
||||
|
||||
|
||||
// 解码验证
|
||||
IotDeviceMessage decoded = codec.decode(packet);
|
||||
log.info("解码后消息ID: {}", decoded.getId());
|
||||
@@ -63,7 +64,7 @@ public class TcpBinaryDataPacketExamples {
|
||||
log.info("解码后服务ID: {}", decoded.getServerId());
|
||||
log.info("解码后上报时间: {}", decoded.getReportTime());
|
||||
log.info("解码后参数: {}", decoded.getParams());
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -72,16 +73,16 @@ public class TcpBinaryDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateHeartbeat(IotTcpBinaryDeviceMessageCodec codec) {
|
||||
log.info("=== 二进制格式心跳包示例 ===");
|
||||
|
||||
|
||||
// 创建心跳消息
|
||||
IotDeviceMessage heartbeat = IotDeviceMessage.requestOf("thing.state.online", null);
|
||||
heartbeat.setDeviceId(123456L);
|
||||
|
||||
|
||||
// 编码
|
||||
byte[] packet = codec.encode(heartbeat);
|
||||
log.info("心跳包长度: {} 字节", packet.length);
|
||||
log.info("心跳包(HEX): {}", bytesToHex(packet));
|
||||
|
||||
|
||||
// 解码验证
|
||||
IotDeviceMessage decoded = codec.decode(packet);
|
||||
log.info("解码后消息ID: {}", decoded.getId());
|
||||
@@ -90,7 +91,7 @@ public class TcpBinaryDataPacketExamples {
|
||||
log.info("解码后设备ID: {}", decoded.getDeviceId());
|
||||
log.info("解码后服务ID: {}", decoded.getServerId());
|
||||
log.info("解码后参数: {}", decoded.getParams());
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -99,40 +100,40 @@ public class TcpBinaryDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateComplexDataReport(IotTcpBinaryDeviceMessageCodec codec) {
|
||||
log.info("=== 二进制格式复杂数据上报示例 ===");
|
||||
|
||||
|
||||
// 创建复杂设备数据
|
||||
Map<String, Object> deviceData = new HashMap<>();
|
||||
|
||||
|
||||
// 环境数据
|
||||
Map<String, Object> environment = new HashMap<>();
|
||||
environment.put("temperature", 23.8);
|
||||
environment.put("humidity", 55.0);
|
||||
environment.put("co2", 420);
|
||||
deviceData.put("environment", environment);
|
||||
|
||||
|
||||
// GPS数据
|
||||
Map<String, Object> location = new HashMap<>();
|
||||
location.put("latitude", 39.9042);
|
||||
location.put("longitude", 116.4074);
|
||||
location.put("altitude", 43.5);
|
||||
deviceData.put("location", location);
|
||||
|
||||
|
||||
// 设备状态
|
||||
Map<String, Object> status = new HashMap<>();
|
||||
status.put("battery", 78);
|
||||
status.put("signal", -65);
|
||||
status.put("online", true);
|
||||
deviceData.put("status", status);
|
||||
|
||||
|
||||
// 创建设备消息
|
||||
IotDeviceMessage message = IotDeviceMessage.requestOf("thing.property.post", deviceData);
|
||||
message.setDeviceId(789012L);
|
||||
|
||||
|
||||
// 编码
|
||||
byte[] packet = codec.encode(message);
|
||||
log.info("复杂数据包长度: {} 字节", packet.length);
|
||||
log.info("复杂数据包(HEX): {}", bytesToHex(packet));
|
||||
|
||||
|
||||
// 解码验证
|
||||
IotDeviceMessage decoded = codec.decode(packet);
|
||||
log.info("解码后消息ID: {}", decoded.getId());
|
||||
@@ -141,7 +142,7 @@ public class TcpBinaryDataPacketExamples {
|
||||
log.info("解码后设备ID: {}", decoded.getDeviceId());
|
||||
log.info("解码后服务ID: {}", decoded.getServerId());
|
||||
log.info("解码后参数: {}", decoded.getParams());
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -164,9 +165,9 @@ public class TcpBinaryDataPacketExamples {
|
||||
log.error("数据包长度不足");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int index = 0;
|
||||
|
||||
|
||||
// 解析包头(4字节) - 后续数据长度
|
||||
int totalLength = ((packet[index] & 0xFF) << 24) |
|
||||
((packet[index + 1] & 0xFF) << 16) |
|
||||
@@ -174,27 +175,27 @@ public class TcpBinaryDataPacketExamples {
|
||||
(packet[index + 3] & 0xFF);
|
||||
index += 4;
|
||||
log.info("包头 - 后续数据长度: {} 字节", totalLength);
|
||||
|
||||
|
||||
// 解析设备地址长度(2字节)
|
||||
int addrLength = ((packet[index] & 0xFF) << 8) | (packet[index + 1] & 0xFF);
|
||||
index += 2;
|
||||
log.info("设备地址长度: {} 字节", addrLength);
|
||||
|
||||
|
||||
// 解析设备地址
|
||||
String deviceAddr = new String(packet, index, addrLength);
|
||||
index += addrLength;
|
||||
log.info("设备地址: {}", deviceAddr);
|
||||
|
||||
|
||||
// 解析功能码(2字节)
|
||||
int functionCode = ((packet[index] & 0xFF) << 8) | (packet[index + 1] & 0xFF);
|
||||
index += 2;
|
||||
log.info("功能码: {} ({})", functionCode, getFunctionCodeName(functionCode));
|
||||
|
||||
|
||||
// 解析消息序号(2字节)
|
||||
int messageId = ((packet[index] & 0xFF) << 8) | (packet[index + 1] & 0xFF);
|
||||
index += 2;
|
||||
log.info("消息序号: {}", messageId);
|
||||
|
||||
|
||||
// 解析包体数据
|
||||
if (index < packet.length) {
|
||||
String payload = new String(packet, index, packet.length - index);
|
||||
|
||||
@@ -7,9 +7,10 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// TODO @haohao:这种写成单测,会好点
|
||||
/**
|
||||
* TCP JSON格式数据包示例
|
||||
*
|
||||
*
|
||||
* 演示如何使用新的JSON格式进行TCP消息编解码
|
||||
*
|
||||
* @author 芋道源码
|
||||
@@ -19,22 +20,22 @@ public class TcpJsonDataPacketExamples {
|
||||
|
||||
public static void main(String[] args) {
|
||||
IotTcpJsonDeviceMessageCodec codec = new IotTcpJsonDeviceMessageCodec();
|
||||
|
||||
|
||||
// 1. 数据上报示例
|
||||
demonstrateDataReport(codec);
|
||||
|
||||
|
||||
// 2. 心跳示例
|
||||
demonstrateHeartbeat(codec);
|
||||
|
||||
|
||||
// 3. 事件上报示例
|
||||
demonstrateEventReport(codec);
|
||||
|
||||
|
||||
// 4. 复杂数据上报示例
|
||||
demonstrateComplexDataReport(codec);
|
||||
|
||||
|
||||
// 5. 便捷方法示例
|
||||
demonstrateConvenienceMethods();
|
||||
|
||||
|
||||
// 6. EMQX兼容性示例
|
||||
demonstrateEmqxCompatibility();
|
||||
}
|
||||
@@ -44,24 +45,24 @@ public class TcpJsonDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateDataReport(IotTcpJsonDeviceMessageCodec codec) {
|
||||
log.info("=== JSON格式数据上报示例 ===");
|
||||
|
||||
|
||||
// 创建传感器数据
|
||||
Map<String, Object> sensorData = new HashMap<>();
|
||||
sensorData.put("temperature", 25.5);
|
||||
sensorData.put("humidity", 60.2);
|
||||
sensorData.put("pressure", 1013.25);
|
||||
sensorData.put("battery", 85);
|
||||
|
||||
|
||||
// 创建设备消息
|
||||
IotDeviceMessage message = IotDeviceMessage.requestOf("thing.property.post", sensorData);
|
||||
message.setDeviceId(123456L);
|
||||
|
||||
|
||||
// 编码
|
||||
byte[] packet = codec.encode(message);
|
||||
String jsonString = new String(packet, StandardCharsets.UTF_8);
|
||||
log.info("编码后JSON: {}", jsonString);
|
||||
log.info("数据包长度: {} 字节", packet.length);
|
||||
|
||||
|
||||
// 解码验证
|
||||
IotDeviceMessage decoded = codec.decode(packet);
|
||||
log.info("解码后消息ID: {}", decoded.getId());
|
||||
@@ -69,7 +70,7 @@ public class TcpJsonDataPacketExamples {
|
||||
log.info("解码后设备ID: {}", decoded.getDeviceId());
|
||||
log.info("解码后服务ID: {}", decoded.getServerId());
|
||||
log.info("解码后参数: {}", decoded.getParams());
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -78,24 +79,24 @@ public class TcpJsonDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateHeartbeat(IotTcpJsonDeviceMessageCodec codec) {
|
||||
log.info("=== JSON格式心跳示例 ===");
|
||||
|
||||
|
||||
// 创建心跳消息
|
||||
IotDeviceMessage heartbeat = IotDeviceMessage.requestOf("thing.state.online", null);
|
||||
heartbeat.setDeviceId(123456L);
|
||||
|
||||
|
||||
// 编码
|
||||
byte[] packet = codec.encode(heartbeat);
|
||||
String jsonString = new String(packet, StandardCharsets.UTF_8);
|
||||
log.info("编码后JSON: {}", jsonString);
|
||||
log.info("心跳包长度: {} 字节", packet.length);
|
||||
|
||||
|
||||
// 解码验证
|
||||
IotDeviceMessage decoded = codec.decode(packet);
|
||||
log.info("解码后消息ID: {}", decoded.getId());
|
||||
log.info("解码后方法: {}", decoded.getMethod());
|
||||
log.info("解码后设备ID: {}", decoded.getDeviceId());
|
||||
log.info("解码后服务ID: {}", decoded.getServerId());
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -104,31 +105,31 @@ public class TcpJsonDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateEventReport(IotTcpJsonDeviceMessageCodec codec) {
|
||||
log.info("=== JSON格式事件上报示例 ===");
|
||||
|
||||
|
||||
// 创建事件数据
|
||||
Map<String, Object> eventData = new HashMap<>();
|
||||
eventData.put("eventType", "alarm");
|
||||
eventData.put("level", "warning");
|
||||
eventData.put("description", "温度过高");
|
||||
eventData.put("value", 45.8);
|
||||
|
||||
|
||||
// 创建事件消息
|
||||
IotDeviceMessage event = IotDeviceMessage.requestOf("thing.event.post", eventData);
|
||||
event.setDeviceId(123456L);
|
||||
|
||||
|
||||
// 编码
|
||||
byte[] packet = codec.encode(event);
|
||||
String jsonString = new String(packet, StandardCharsets.UTF_8);
|
||||
log.info("编码后JSON: {}", jsonString);
|
||||
log.info("事件包长度: {} 字节", packet.length);
|
||||
|
||||
|
||||
// 解码验证
|
||||
IotDeviceMessage decoded = codec.decode(packet);
|
||||
log.info("解码后消息ID: {}", decoded.getId());
|
||||
log.info("解码后方法: {}", decoded.getMethod());
|
||||
log.info("解码后设备ID: {}", decoded.getDeviceId());
|
||||
log.info("解码后参数: {}", decoded.getParams());
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -137,10 +138,10 @@ public class TcpJsonDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateComplexDataReport(IotTcpJsonDeviceMessageCodec codec) {
|
||||
log.info("=== JSON格式复杂数据上报示例 ===");
|
||||
|
||||
|
||||
// 创建复杂设备数据(类似EMQX格式)
|
||||
Map<String, Object> deviceData = new HashMap<>();
|
||||
|
||||
|
||||
// 环境数据
|
||||
Map<String, Object> environment = new HashMap<>();
|
||||
environment.put("temperature", 23.8);
|
||||
@@ -148,7 +149,7 @@ public class TcpJsonDataPacketExamples {
|
||||
environment.put("co2", 420);
|
||||
environment.put("pm25", 35);
|
||||
deviceData.put("environment", environment);
|
||||
|
||||
|
||||
// GPS数据
|
||||
Map<String, Object> location = new HashMap<>();
|
||||
location.put("latitude", 39.9042);
|
||||
@@ -156,7 +157,7 @@ public class TcpJsonDataPacketExamples {
|
||||
location.put("altitude", 43.5);
|
||||
location.put("speed", 0.0);
|
||||
deviceData.put("location", location);
|
||||
|
||||
|
||||
// 设备状态
|
||||
Map<String, Object> status = new HashMap<>();
|
||||
status.put("battery", 78);
|
||||
@@ -164,24 +165,24 @@ public class TcpJsonDataPacketExamples {
|
||||
status.put("online", true);
|
||||
status.put("version", "1.2.3");
|
||||
deviceData.put("status", status);
|
||||
|
||||
|
||||
// 创建设备消息
|
||||
IotDeviceMessage message = IotDeviceMessage.requestOf("thing.property.post", deviceData);
|
||||
message.setDeviceId(789012L);
|
||||
|
||||
|
||||
// 编码
|
||||
byte[] packet = codec.encode(message);
|
||||
String jsonString = new String(packet, StandardCharsets.UTF_8);
|
||||
log.info("编码后JSON: {}", jsonString);
|
||||
log.info("复杂数据包长度: {} 字节", packet.length);
|
||||
|
||||
|
||||
// 解码验证
|
||||
IotDeviceMessage decoded = codec.decode(packet);
|
||||
log.info("解码后消息ID: {}", decoded.getId());
|
||||
log.info("解码后方法: {}", decoded.getMethod());
|
||||
log.info("解码后设备ID: {}", decoded.getDeviceId());
|
||||
log.info("解码后参数: {}", decoded.getParams());
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -190,9 +191,9 @@ public class TcpJsonDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateConvenienceMethods() {
|
||||
log.info("=== 便捷方法示例 ===");
|
||||
|
||||
|
||||
IotTcpJsonDeviceMessageCodec codec = new IotTcpJsonDeviceMessageCodec();
|
||||
|
||||
|
||||
// 使用便捷方法编码数据上报
|
||||
Map<String, Object> sensorData = Map.of(
|
||||
"temperature", 26.5,
|
||||
@@ -200,11 +201,11 @@ public class TcpJsonDataPacketExamples {
|
||||
);
|
||||
byte[] dataPacket = codec.encodeDataReport(sensorData, 123456L, "smart_sensor", "device_001");
|
||||
log.info("便捷方法编码数据上报: {}", new String(dataPacket, StandardCharsets.UTF_8));
|
||||
|
||||
|
||||
// 使用便捷方法编码心跳
|
||||
byte[] heartbeatPacket = codec.encodeHeartbeat(123456L, "smart_sensor", "device_001");
|
||||
log.info("便捷方法编码心跳: {}", new String(heartbeatPacket, StandardCharsets.UTF_8));
|
||||
|
||||
|
||||
// 使用便捷方法编码事件
|
||||
Map<String, Object> eventData = Map.of(
|
||||
"eventType", "maintenance",
|
||||
@@ -212,7 +213,7 @@ public class TcpJsonDataPacketExamples {
|
||||
);
|
||||
byte[] eventPacket = codec.encodeEventReport(eventData, 123456L, "smart_sensor", "device_001");
|
||||
log.info("便捷方法编码事件: {}", new String(eventPacket, StandardCharsets.UTF_8));
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@@ -221,7 +222,7 @@ public class TcpJsonDataPacketExamples {
|
||||
*/
|
||||
private static void demonstrateEmqxCompatibility() {
|
||||
log.info("=== EMQX格式兼容性示例 ===");
|
||||
|
||||
|
||||
// 模拟EMQX风格的消息格式
|
||||
String emqxStyleJson = """
|
||||
{
|
||||
@@ -235,19 +236,19 @@ public class TcpJsonDataPacketExamples {
|
||||
"timestamp": 1642781234567
|
||||
}
|
||||
""";
|
||||
|
||||
|
||||
IotTcpJsonDeviceMessageCodec codec = new IotTcpJsonDeviceMessageCodec();
|
||||
|
||||
|
||||
// 解码EMQX风格的消息
|
||||
byte[] emqxBytes = emqxStyleJson.getBytes(StandardCharsets.UTF_8);
|
||||
IotDeviceMessage decoded = codec.decode(emqxBytes);
|
||||
|
||||
|
||||
log.info("EMQX风格消息解码成功:");
|
||||
log.info("消息ID: {}", decoded.getId());
|
||||
log.info("方法: {}", decoded.getMethod());
|
||||
log.info("设备ID: {}", decoded.getDeviceId());
|
||||
log.info("参数: {}", decoded.getParams());
|
||||
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user