我是靠谱客的博主 开放黑夜,最近开发中收集的这篇文章主要介绍MQTT-SN协议乱翻之消息格式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

紧接着上篇初步介绍,本文为第二篇,主要梳理MQTT-SN 1.2协议中定义的消息格式。

通用消息格式

消息头其它可变部分
2/4字节表示N字节组成

消息头部

长度消息类型
1或3个字节1个字节
  • 长度要么是1个字节,要么3个字节表示,并且自身也会包含在其内。一个字节可表示256长度,一般情况下,完全够用了。
  • 只需要判断第一个字节是否为 0x01,若是那么长度为3个字节表示,剩下的两个字节会表示真正的消息长度,最大长度为65535
  • 否则长度就是一个字节表示,256个长度,大部分消息长度都是一个字节,除非特别提醒

备注:

 MQTT-SN不支持消息的分片和重组。底层网络所定义数据包长度若小于MQTT-SN消息的最大长度,自身进行的分片和重组,对MQTT-SN协议本身不受影响。

MQTT-SN消息类型

MQTT-SN定义的消息类型数量众多,超过25个,感觉有些头大。

消息类型值消息类型名称说明
0x00ADVERTISE广播消息
0x01SEARCHGW寻找网关
0x02GWINFO网关信息
0x03reserved没有使用到
0x04CONNECT发起连接
0x05CONNACK连接确认
0x06WILLTOPICREQ遗嘱主题请求
0x07WILLTOPIC遗嘱主题确认
0x08WILLMSGREQ遗嘱消息请求
0x09WILLMSG遗嘱消息确认
0x0AREGISTER注册主题
0x0BREGACK注册确认
0x0CPUBLISH发布消息
0x0DPUBACK发布确认
0x0EPUBCOMP发布环节消息
0x0FPUBREC发布环节消息
0x10PUBREL发布环节消息
0x11reserved保留字段
0x12SUBSCRIBE订阅主题
0x13SUBACK订阅确认
0x14UNSUBSCRIBE退订
0x15UNSUBACK退订确认
0x16PINGREQPing请求
0x17PINGRESPPing响应
0x18DISCONNECT断开
0x19reserved保留字段
0x1AWILLTOPICUPD遗嘱主题更新
0x1BWILLTOPICRESP遗嘱主题更新确认
0x1CWILLMSGUPD遗嘱消息更新
0x1DWILLMSGRESP遗嘱消息更新确认
0x1E-0xFDreserved保留字段
0xFE转发封装标志用于转发

消息可变部分

可变字段很多,与MQTT相比,多了:

  1. 持续时长字段(Duration)
  2. 标识符Flags有所不同,下面表格进行说明
  3. 网关地址(GwAdd),可变长度,但依赖于底层网络,在ZigBee网络中2个字节长度
  4. 一个字节网关Id(GwId)
  5. 协议Id(ProtocolId),一个字节,唯一值 0x01,统一表示协议名称和协议名称
  6. 广播路径跳数(广播路径深度/广播辐射范围),Radius,一个字节表示,0x00表示广播给当前网络中所有节点
  7. CONNECT/REGISTER/SUBSCRIBE/PUBLISH等消息对应回执中都会包含返回码Recode Code,见下表格
返回值返回值含义
0x00接受请求(Accepted)
0x01因拥塞拒绝(Rejected: congestion),一般需要接收方等待T_WAIT时间长
0x02因非法主题标识符拒绝(Rejected: invalid topic ID)
0x03因不支持拒绝(Rejected: not supported)
0x04 - 0xFF保留,没有使用到

具体消息格式说明

网关周期性会对当前网络下所有客户端、节点进行广播,用于客户端发现可用网关。

字节索引表示内容说明
0Length0x05
1MsgType0x00
2GwId网关需要吧自身标识符包含其中
3-4Duration网关的下次广播间隔时长,单位秒

SEARCHGW

字节索引表示内容说明
0Length0x03
1MsgType0x01
2Radius广播半径深度,同时也是只是给当前网络传输层

客户端主动寻找网关进行广播的消息,广播路径范围受限于当前网络环境下的客户端部署密度,比如只有1跳广播在非常密集的网络环境下客户端都可以彼此互相访问。

GWINFO

字节索引表示内容说明
0Length动态确定
1MsgType0x02
2GwId网关Id
3-nGwAdd*一个网关地址,仅仅由客户端发出消息时,此字段才存在

GWINFO作为对SEARCHGW消息的响应:

  • 若由网关发出,则无GwAdd字段
  • 若来自于客户端,需要包含网关地址

CONNECT

客户端向网关发出建立连接的消息。

字节索引表示内容说明
0Length动态计算
1MsgType0x04
2Flags标志位
3ProtocolId0x01,表示协议版本和协议名称
4-5Duration存活持续时长
6-nClientId客户端标识符,1-23个字节表示的字符串

在CONNECT消息标志位具体表示如下:

DUPQoSRetainWillCleanSessionTopicIdType
bit 76,54321,0
XXX0/10/1X
  • 0/1 表示具体值待定
  • X 表示没有使用到

在Flags中使用到的标志位:

  1. Will:若为1,客户端会在稍后请求遗嘱主题和遗嘱消息
  2. CleanSession:不但表示订阅持久化,同时也被可扩展到遗嘱主题和遗嘱消息中

CONNACK

网关对客户端发出CONNECT消息的响应。

字节索引表示内容说明
0Length0x03
1MsgType0x05
2ReturnCode接受值0x00,拒绝为0x01-0x03,具体见上文RecodeCode定义

WILLTOPICREQ

根据客户端CONNECT标志位中WILL字段为true情况下,网关向客户端发出遗嘱主题请求,格式如下:

字节索引表示内容说明
0Length0x02
1MsgType0x06

只有头部部分,很简单。

WILLTOPIC

客户端作为网关WILLTOPICREQ请求响应消息。下面是一个正常版本的WILLTOPIC消息:

字节索引表示内容说明
0Length动态计算
1MsgType0x07
2Flags标志位
3-nWillTopic遗嘱主题

此时的标志位如下

DUPQoSRetainWillCleanSessionTopicIdType
bit 76,54321,0
X0x00-0x020/1XXX

而空的WILLTOPIC也是允许存在的,就两个字节表示,用于客户端请求删除已存在于服务器端的对应遗嘱主题和消息。

字节索引表示内容说明
0Length0x02
1MsgType0x07

WILLMSGREQ

根据客户端CONNECT标志位中WILL字段为真情况下,网关向客户端发出遗嘱消息请求,格式如下:

字节索引表示内容说明
0Length0x02
1MsgType0x08

只有头部部分,没有别的。

WILLMSG

客户端对网关WILLMSGREQ请求的响应,从而把遗嘱消息传递给网关进行保存。

字节索引表示内容说明
0Length动态计算
1MsgType0x09
2-nWillMsg客户端遗嘱

REGISTER

  • 客户端-->网关,请求主题(topic name)对应的主题标识符(topic id)
  • 网关-->客户端,通知主题(topic name)已经被指派到某个主题标识符(topic id)
字节索引表示内容说明
0Length动态计算
1MsgType0x0A
2-3TopicId客户端发出,此值为0x0000;服务器发出,需要包含对应于Topic Name的主题标识符
4-5MsgId自然数,用以标识对应的REGACK确认
6-nTopicName主题名称,不能太长,尽量不要使用通配符

REGACK

客户端或网关针对REGISTER消息的响应。

字节索引表示内容说明
0Length0x07
1MsgType0x0B
2-3TopicId对应于Topic Name的主题标识符,被用于PUBLISH消息发布
4-5MsgId自然数,用以标识对应的REGISTER消息
6ReturnCode0x00被接受,其它值被拒绝

PUBLISH

PUBLISH消息用于客户端或网关发布消息用:

字节索引表示内容说明
0Length动态计算
1MsgType0x0C
2Flags标志位
3-4TopicId主题标识符
5-6MsgIdQoS 1-2时需要填充自然值;QoS 0时,值为0x0000
7-nData用于发布的具体消息内容

标识位具体如下:

DUPQoSRetainWillCleanSessionTopicIdType
bit 76,54321,0
0/10x00-0x020/1XX0b00/0b01/0b10

标识位里面各个字段和MQTT协议一致,无须多解释。

PUBACK

客户端/网关仅仅对QoS 1/2的PUBLISH消息做出响应。

字节索引表示内容说明
0Length0x07
1MsgType0x0D
2-3TopicId对应PUBLISH消息中TopicId
4-5MsgId自然数,用以标识对应的REGISTER消息
6ReturnCode0x00被接受,其它值被拒绝,不同值表示不同拒绝理由

处理PUBLISH消息异常?在PUBACK消息中的ReturnCode字段中以相应值体现出来,这就要求接收者处理拒绝理由。

PUBREC, PUBREL, PUBCOMP

只有在PUBLISH消息中QoS 2时,PUBREC, PUBREL, PUBCOMP才会一起登场,否则是没有出场机会的。消息格式嘛,都很统一:

字节索引表示内容说明
0Length0x04
1MsgType0x0F/0x10/0x0E
2-3MsgId对应PUBLISH消息中的MsgId

SUBSCRIBE

SUBSCRIBE用于客户端订阅某个主题的消息。

字节索引表示内容说明
0Length动态计算
1MsgType0x12
2Flags标志位
3-4MsgId用于确定对应的订阅确认SUBACK消息
5-NTopicId/TopicName具体需要根据Flags标志位中TopicIdType进行填充

标识位具体如下:

DUPQoSRetainWillCleanSessionTopicIdType
bit 76,54321,0
0/10x00-0x02XXX0b00/0b01/0b10

此处,标志位中TopicIdType决定了SUBSCRIBE消息中TopicId/TopicName字段具体填充值:预定义topic id,或短小两个字符表示主题(topic name),或直接填写主题。

SUBACK

网关->客户端,订阅处理情况的确认回执,接受订阅或出于其它原因拒绝之。

字节索引表示内容说明
0Length0x08
1MsgType0x13
2Flags标志位
3-4TopicId网关接受其注册,此处对应具体指派的TopicId
5-6MsgIdSUBSCRIBE消息中对应MsgId值
7ReturnCode0x00被接受,其它值被拒绝

标识位具体如下:

DUPQoSRetainWillCleanSessionTopicIdType
bit 76,54321,0
X0x00-0x02XXXX

SUBACK消息标志位中QoS为网关根据实际情况授权后的QoS具体值,这也应该是客户端需要知道并处理的。

UNSUBSCRIBE

UNSUBSCRIBE用于客户端取消订阅某个主题的消息。

字节索引表示内容说明
0Length动态计算
1MsgType0x14
2Flags标志位
3-4MsgId用于确定对应的退订确认UNSUBACK消息
5-NTopicId/TopicName具体需要根据Flags标志位中TopicIdType进行填充

标识位具体如下:

DUPQoSRetainWillCleanSessionTopicIdType
bit 76,54321,0
XXXXX0b00/0b01/0b10

UNSUBSCRIBE消息标志位中唯一可用属性TopicIdType决定了UNSUBSCRIBE消息中TopicId/TopicName字段具体填充值。

UNSUBACK

网关->客户端,取消订阅处理情况的确认回执,很简单,4个字节表示。

字节索引表示内容说明
0Length0x04
1MsgType0x15
2-3MsgIdUNSUBSCRIBE消息中对应MsgId值

PINGREQ

和MQTT协议中的PINGREQ一致,存活检测。

字节索引表示内容说明
0Length动态计算
1MsgType0x16
2-NClientId可选项,表示客户端休眠状态转换为唤醒状态用于检查网关是否为其缓存消息

PINGRESP

接受PINGREQ消息的一方,如网关响应PINGRESP消息表示自己现在运行OK。

另外一个意图,若唤醒状态客户端发送PINGREQ消息之后,直接收到PINGRESP消息,表示网关当前暂时没有为其缓存的消息可供发送。

字节索引表示内容说明
0Length0x02
1MsgType0x17

很简单,两个字节表示足矣。

DISCONNECT

字节索引表示内容说明
0Length动态计算
1MsgType0x18
2-3Duration可选项,表示客户端即将进入睡眠状态的持续时间值
  • 客户端->网关,客户端主动关闭当前连接,网关响应确认消息。只有表示自己进入睡眠状态的客户端,才会在DISCONNECT消息中附加Duration持续字段。
  • 网关->客户端,网关由于异常主动通知客户端关闭两者之间连接,客户端接收到DISCONNECT时需要发送CONNECT消息到网关,重试重新建立连接。没有Duration字段填充。

网关接收到要进入休眠状态的客户端发送的包含有Duration字段DISCONNECT消息时,可以直接返回2个字节的(不能包含有Duration字段)DISCONNECT消息以示确认。

WILLTOPICUPD

客户端发送请求网关更新其遗嘱主题。

字节索引表示内容说明
0Length动态计算
1MsgType0x1A
2Flags标志位
3-NWillTopic用于更新的遗嘱主题

标识位具体如下:

DUPQoSRetainWillCleanSessionTopicIdType
bit 76,54321,0
X0x00-0x020/1XXX

协议规定只有两个字节空WILLTOPICUPD也是允许存在的,存在意义用于客户端请求网关删除已保存的遗嘱主题和遗嘱消息等。

字节索引表示内容说明
0Length0x02
1MsgType0x1A

WILLTOPICRESP

WILLTOPICRESP为网关收到WILLTOPICUPD后作出的应答消息。

字节索引表示内容说明
0Length0x03
1MsgType0x1B
2ReturnCode0x00被接受,其它值被拒绝

WILLMSGUPD

字节索引表示内容说明
0Length动态计算
1MsgType0x1C
2-NWillMsg用于更新的遗嘱消息

客户端->网关,确认更新的遗嘱消息。

WILLMSGRESP

WILLMSGRESP为网关收到WILLMSGUPD后作出的应答消息。

字节索引表示内容说明
0Length0x03
1MsgType0x1D
2ReturnCode0x00被接受,其它值被拒绝

转发封装

在MQTT-SN架构图中,MQTT-SN Forwarder转发器适用于客户端无法直接访问网关或当前传感器网络区域中不存在网关时,转发器作用就体现出来了:

  1. 接收MQTT-SN客户端消息封装后转发给上游网关
  2. 解封上游网关所发送消息,直接发送给对应客户端

转发器作用于消息的封装转发,解封发送,针对消息不做修改。

转发器对MQTT-SN消息封装格式:

字节索引表示内容说明
0Length十进制表示长度就是N
1MsgType0xFE
2Ctrl包含网关和转发器之间的控制交换信息,主要是前两位包含了半径范围
3-NWireless Node Id标识所发目的或需要接收封装消息的无线节点
N+1-MMQTT-SN message一个MQTT-SN消息消息

无线节点Id(Wireless Node Id):

  • 转发器->网关,无线节点Id为转发器所在的无线节点Id,便于告知网关转发器位置
  • 网关->转发器,无线节点Id为网关的无线节点Id

控制交换字段Ctrl,单个字节,位表示含义:

bit 7,21,0
X0x00-0x03

小结

MQTT-SN 1.2规范中所定义消息格式介绍完毕,下一篇将对MQTT-SN主要流程功、能进行阐述。

 原文 http://www.blogjava.net/yongboy/archive/2015/01/08/422142.html

转载于:https://www.cnblogs.com/yudar/p/4642475.html

最后

以上就是开放黑夜为你收集整理的MQTT-SN协议乱翻之消息格式的全部内容,希望文章能够帮你解决MQTT-SN协议乱翻之消息格式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部