From ff7e796a09a94f7b374e881e58328707c42fedf6 Mon Sep 17 00:00:00 2001 From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com> Date: Wed, 24 Jan 2024 19:22:33 +0800 Subject: [PATCH] =?UTF-8?q?doc:=20=E5=AE=8C=E5=96=84TCP=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E5=86=85=E5=AE=B9=20(#16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc: 完善TCP文档内容 * doc: 增加设备上报示例 * doc: 增加请求设备上线示例 * doc: 文档增加byteBuf构建示例 * doc: 使用databuffer构建报文 --- binary-protocol.md | 216 ++++++++++++++++++++++++++++++--------------- 1 file changed, 147 insertions(+), 69 deletions(-) diff --git a/binary-protocol.md b/binary-protocol.md index d6d5fb7..f10115a 100644 --- a/binary-protocol.md +++ b/binary-protocol.md @@ -1,89 +1,167 @@ ## 头信息 -| 字节序 | 类型 | 字段 | -|:----:|---------|:-----------:| -| 0 | INT8 | 消息类型 | -| 1-8 | INT64 | UTC时间戳 | -| 9-11 | INT16 | 消息序号 | -| 12-n | STRING | 设备ID | -| ... | MESSAGE | 消息类型对应的编码规则 | +| 字节数 | 类型 | 字段 | 备注 | +| :----: | ------- | :--------------------: | ------------------- | +| n | 自定 | 消息长度 | 平台配置项 | +| 1 | INT8 | 消息类型 | 见消息类型定义 | +| 8 | INT64 | UTC时间戳 | | +| 2 | INT16 | 消息序号 | | +| 2 | INT16 | 设备ID长度 | | +| n | STRING | 设备ID | 根据设备ID长度得出 | +| n | MESSAGE | 消息类型对应的编码规则 | | +| 2 | INT16 | secureKeyLength | TCP认真配置密钥长度 | +| n | STRING | secureKey | 密钥 | ## 数据类型 所有数据类型均采用`大端`编码 -| Byte | Type | 编码规则 | -|:----:|:-------:|---------------------------------------------| -| 0x00 | NULL | 0x01 | -| 0x01 | BOOLEAN | 1字节 0x00为false 其他为true | -| 0x02 | INT8 | 1字节 (byte) | -| 0x03 | INT16 | 2字节整型 (short) | -| 0x04 | INT32 | 4字节整型 (int) | -| 0x05 | INT64 | 8字节整型 (long) | -| 0x06 | UINT8 | 1字节无符号整型 | -| 0x07 | UINT16 | 2字节无符号整型 | -| 0x08 | UINT32 | 4字节无符号整型 | -| 0x09 | FLOAT | 4字节 IEEE 754浮点数 | -| 0x0a | DOUBLE | 8字节 IEEE 754浮点数 | -| 0x0b | STRING | 前`2字节无符号整型`表示字符串长度,接下来长度的字节为字符串内容,UTF8编码 | -| 0x0c | BINARY | 前`2字节无符号整型`表示数据长度,接下来长度的字节为数据内容 | -| 0x0d | ARRAY | 前`2字节无符号整型`表述数组长度,接下来根据后续报文类型来解析元素 | -| 0x0e | OBJECT | 前`2字节无符号整型`表述对象字段长度,接下来根据后续报文类型来解析key value | +| Byte | Type | 编码规则 | 备注 | +| :--: | :-----: | ------------------------------------------------------------ | ------------------------------------------------------------ | +| 0x00 | NULL | | | +| 0x01 | BOOLEAN | 1字节 0x00为false 其他为true | | +| 0x02 | INT8 | 1字节 (byte) | | +| 0x03 | INT16 | 2字节整型 (short) | | +| 0x04 | INT32 | 4字节整型 (int) | | +| 0x05 | INT64 | 8字节整型 (long) | | +| 0x06 | UINT8 | 1字节无符号整型 | | +| 0x07 | UINT16 | 2字节无符号整型 | | +| 0x08 | UINT32 | 4字节无符号整型 | | +| 0x09 | FLOAT | 4字节 IEEE 754浮点数 | | +| 0x0a | DOUBLE | 8字节 IEEE 754浮点数 | | +| 0x0b | STRING | 前`2字节无符号整型`表示字符串长度,接下来长度的字节为字符串内容,UTF8编码 | 2+N,2个字节(UnsignedShort)表示N的长度 | +| 0x0c | BINARY | 前`2字节无符号整型`表示数据长度,接下来长度的字节为数据内容 | 2+N,2个字节(UnsignedShort)表示N的长度 | +| 0x0d | ARRAY | 前`2字节无符号整型`表述数组长度,接下来根据后续报文类型来解析元素 | 2+N,2个字节(UnsignedShort)表示ARRAY的长度N=很多*(1+X),1个字节(UnsignedShort)表示X的数据类型,X表示长度,见上几行。 | +| 0x0e | OBJECT | 前`2字节无符号整型`表述对象字段长度,接下来根据后续报文类型来解析key value | 2+N,2个字节(UnsignedShort)表示OBJECT的长度,N是STRING+数据类型的组合了(见上几行)。 | ## 消息类型定义 -| Byte | Type | 说明 | -|:----:|:-------------------|--------| -| 0x00 | keepalive | 心跳 | -| 0x01 | online | 首次连接 | -| 0x02 | ack | 应答 | -| 0x03 | reportProperty | 上报属性 | -| 0x04 | readProperty | 读取属性 | -| 0x05 | readPropertyReply | 读取属性回复 | -| 0x06 | writeProperty | 修改属性 | -| 0x07 | writePropertyReply | 修改属性回复 | -| 0x08 | function | 功能调用 | -| 0x09 | functionReply | 功能调用回复 | +| Byte | Type | 说明 | Message示例 | +| :--: | :----------------- | ------------ | ------------------------------------------------------------ | +| 0x00 | keepalive | 心跳 | | +| 0x01 | online | 首次连接 | [STRING:密钥信息 ] | +| 0x02 | ack | 应答 | [应答码 ]
应答码: 0x00:ok , 0x01: 未认证, 0x02: 不支持. | +| 0x03 | reportProperty | 上报属性 | [属性数据:OBJECT类型 ] | +| 0x04 | readProperty | 读取属性 | [属性列表:ARRAY类型 ] | +| 0x05 | readPropertyReply | 读取属性回复 | 读取成功:[`0x01`,属性数据:OBJECT类型 ]
读取失败:[`0x00`,错误码:动态类型,错误消息:动态类型 ] | +| 0x06 | writeProperty | 修改属性 | [属性列表:OBJECT类型 ] | +| 0x07 | writePropertyReply | 修改属性回复 | 修改成功:[`0x01`,属性数据:OBJECT类型 ]
修改失败:[`0x00`,错误码:动态类型,错误消息:动态类型 ] | +| 0x08 | function | 功能调用 | [功能ID:STRING类型,功能参数:OBJECT类型 ] | +| 0x09 | functionReply | 功能调用回复 | 调用成功:[`0x01`,属性数据:OBJECT类型 ]
调用失败:[`0x00`,错误码:动态类型,错误消息:动态类型 ] | -### 0x00 keepalive 心跳 - -[ 0x00 ] - -### 0x01 online 首次连接 - -[ 0x01,STRING:密钥信息 ] - -### 0x02 ack 应答 - -[ 0x02,应答码 ] - -应答码: 0x00:ok , 0x01: 未认证, 0x02: 不支持. - -### 0x03 reportProperty 上报属性 - -[ 0x03,属性数据:OBJECT类型 ] - -### 0x04 readProperty 读取属性 - -[ 0x04,属性列表:ARRAY类型 ] - -### 0x05 readPropertyReply 读取属性回复 - -读取成功: - -[ 0x05,`0x01`,属性数据:OBJECT类型 ] - -读取失败: -[ 0x05,`0x00`,错误码:动态类型,错误消息:动态类型 ] +### 备注 `动态读取`表示类型不确定,根据对应的`数据类型`来定义类型. 如: 无错误信息 -[ 0x05,0x00,`0x00`,`0x00` ] +[ 0x00,`0x00`,`0x00` ] `INT8(0x02)`类型错误码:`0x04` -[ 0x05,0x00,`0x02,0x04`,0x00 ] +[0x00,`0x02,0x04`,0x00 ] -TODO 更多消息类型 \ No newline at end of file +## 示例 + +### 设备上线 + +``` +000000270100000186c51a890f0001001331363531383533343133303332383934343634000561646d696e +``` + +```java + String hexForOnline = + "00000027" +//消息长度 + "01" + //请求上线 + "00000186c51a890f" +//时间戳 + "0001" +//消息序号 + "0013" +//设备ID长度 + "31363531383533343133303332383934343634" +//设备ID + "0005" +//secureKey长度 + "61646d696e";//平台配置的secureKey + //构建方式一:使用byteBuf构建上线消息 + String deviceId = "1651853413032894464"; + String secureKey = "admin"; + ByteBuf data = Unpooled + .buffer() + .writeByte(0x01) + .writeLong(System.currentTimeMillis()) + .writeShort(1) + .writeShort(deviceId.getBytes().length) + .writeBytes(deviceId.getBytes()) + .writeShort(secureKey.getBytes().length) + .writeBytes(secureKey.getBytes()); + ByteBuf onlineBuf = Unpooled.buffer() + .writeInt(data.readableBytes()) + .writeBytes(data); + //构建方式二:使用jetlinks-core构建消息 + DeviceOnlineMessage message = new DeviceOnlineMessage(); + message.setDeviceId("1651853413032894464"); + message.addHeader(BinaryDeviceOnlineMessage.loginToken, "admin"); + message.setMessageId("1"); + message.setTimestamp(1678344096015L); + ByteBuf byteBuf = BinaryMessageType.write(message, Unpooled.buffer()); + ByteBuf buf = Unpooled + .buffer() + .writeInt(byteBuf.readableBytes()) + .writeBytes(byteBuf); +``` + + + +### 设备数据上报 + +``` +0000006C0300000186C567FA7900020013313635313835333431333033323839343436340001000474656d700B000433362e35000561646d696e +``` + +```java + String hexForReport = + "0000006C" +//消息长度 + "03" +//上报消息 + "00000186C567FA79" + //时间戳 + "0002" +//消息序号 + "0013" +//设备ID长度 + "31363531383533343133303332383934343634" +//设备ID + "0001" + //OBJECT对象数量 + "0004" +//key的长度 + "74656d70" + //值 + "0B" + //value的类型 + "0004" +//Value的长度 + "33362e35" + //值 + "0005" + //secureKey长度 + "61646d696e";//平台配置的secureKey +//构建方式一 + String deviceId = "1651853413032894464"; + String secureKey = "admin"; + String key = "temp"; + String value = "36.5"; + ByteBuf data = Unpooled + .buffer() + .writeByte(0x03) + .writeLong(System.currentTimeMillis()) + .writeShort(2) + .writeShort(deviceId.getBytes().length) + .writeBytes(deviceId.getBytes()) + .writeShort(1) + .writeShort(key.getBytes().length) + .writeBytes(key.getBytes()) + .writeByte(0x0B) + .writeShort(value.getBytes().length) + .writeBytes(value.getBytes()) + .writeShort(secureKey.getBytes().length) + .writeBytes(secureKey.getBytes()); + ByteBuf reportBuf = Unpooled.buffer() + .writeInt(data.readableBytes()) + .writeBytes(data); +//构建方式二 + ReportPropertyMessage message = new ReportPropertyMessage(); + message.setDeviceId("1651853413032894464"); + message.addHeader(BinaryDeviceOnlineMessage.loginToken, "admin"); + message.setMessageId("2"); + message.setProperties(Collections.singletonMap("temp", 32.88)); + ByteBuf data = BinaryMessageType.write(message, Unpooled.buffer()); + ByteBuf buf = Unpooled.buffer() + .writeInt(data.readableBytes()) + .writeBytes(data); +``` \ No newline at end of file