标签:
紧接着上篇初步介绍,本文为第二篇,主要梳理MQTT-SN 1.2协议中定义的消息格式。
消息头 | 其它可变部分 |
---|---|
2/4字节表示 | N字节组成 |
长度 | 消息类型 |
---|---|
1或3个字节 | 1个字节 |
备注:
MQTT-SN不支持消息的分片和重组。底层网络所定义数据包长度若小于MQTT-SN消息的最大长度,自身进行的分片和重组,对MQTT-SN协议本身不受影响。
MQTT-SN定义的消息类型数量众多,超过25个,感觉有些头大。
消息类型值 | 消息类型名称 | 说明 |
---|---|---|
0x00 | ADVERTISE | 广播消息 |
0x01 | SEARCHGW | 寻找网关 |
0x02 | GWINFO | 网关信息 |
0x03 | reserved | 没有使用到 |
0x04 | CONNECT | 发起连接 |
0x05 | CONNACK | 连接确认 |
0x06 | WILLTOPICREQ | 遗嘱主题请求 |
0x07 | WILLTOPIC | 遗嘱主题确认 |
0x08 | WILLMSGREQ | 遗嘱消息请求 |
0x09 | WILLMSG | 遗嘱消息确认 |
0x0A | REGISTER | 注册主题 |
0x0B | REGACK | 注册确认 |
0x0C | PUBLISH | 发布消息 |
0x0D | PUBACK | 发布确认 |
0x0E | PUBCOMP | 发布环节消息 |
0x0F | PUBREC | 发布环节消息 |
0x10 | PUBREL | 发布环节消息 |
0x11 | reserved | 保留字段 |
0x12 | SUBSCRIBE | 订阅主题 |
0x13 | SUBACK | 订阅确认 |
0x14 | UNSUBSCRIBE | 退订 |
0x15 | UNSUBACK | 退订确认 |
0x16 | PINGREQ | Ping请求 |
0x17 | PINGRESP | Ping响应 |
0x18 | DISCONNECT | 断开 |
0x19 | reserved | 保留字段 |
0x1A | WILLTOPICUPD | 遗嘱主题更新 |
0x1B | WILLTOPICRESP | 遗嘱主题更新确认 |
0x1C | WILLMSGUPD | 遗嘱消息更新 |
0x1D | WILLMSGRESP | 遗嘱消息更新确认 |
0x1E-0xFD | reserved | 保留字段 |
0xFE | 转发封装标志 | 用于转发 |
可变字段很多,与MQTT相比,多了:
返回值 | 返回值含义 |
---|---|
0x00 | 接受请求(Accepted) |
0x01 | 因拥塞拒绝(Rejected: congestion),一般需要接收方等待T_WAIT时间长 |
0x02 | 因非法主题标识符拒绝(Rejected: invalid topic ID) |
0x03 | 因不支持拒绝(Rejected: not supported) |
0x04 - 0xFF | 保留,没有使用到 |
网关周期性会对当前网络下所有客户端、节点进行广播,用于客户端发现可用网关。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x05 |
1 | MsgType | 0x00 |
2 | GwId | 网关需要吧自身标识符包含其中 |
3-4 | Duration | 网关的下次广播间隔时长,单位秒 |
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x03 |
1 | MsgType | 0x01 |
2 | Radius | 广播半径深度,同时也是只是给当前网络传输层 |
客户端主动寻找网关进行广播的消息,广播路径范围受限于当前网络环境下的客户端部署密度,比如只有1跳广播在非常密集的网络环境下客户端都可以彼此互相访问。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态确定 |
1 | MsgType | 0x02 |
2 | GwId | 网关Id |
3-n | GwAdd* | 一个网关地址,仅仅由客户端发出消息时,此字段才存在 |
GWINFO作为对SEARCHGW消息的响应:
客户端向网关发出建立连接的消息。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x04 |
2 | Flags | 标志位 |
3 | ProtocolId | 0x01,表示协议版本和协议名称 |
4-5 | Duration | 存活持续时长 |
6-n | ClientId | 客户端标识符,1-23个字节表示的字符串 |
在CONNECT消息标志位具体表示如下:
DUP | QoS | Retain | Will | CleanSession | TopicIdType |
---|---|---|---|---|---|
bit 7 | 6,5 | 4 | 3 | 2 | 1,0 |
X | X | X | 0/1 | 0/1 | X |
在Flags中使用到的标志位:
网关对客户端发出CONNECT消息的响应。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x03 |
1 | MsgType | 0x05 |
2 | ReturnCode | 接受值0x00,拒绝为0x01-0x03,具体见上文RecodeCode定义 |
根据客户端CONNECT标志位中WILL字段为true情况下,网关向客户端发出遗嘱主题请求,格式如下:
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x02 |
1 | MsgType | 0x06 |
只有头部部分,很简单。
客户端作为网关WILLTOPICREQ请求响应消息。下面是一个正常版本的WILLTOPIC消息:
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x07 |
2 | Flags | 标志位 |
3-n | WillTopic | 遗嘱主题 |
此时的标志位如下
DUP | QoS | Retain | Will | CleanSession | TopicIdType |
---|---|---|---|---|---|
bit 7 | 6,5 | 4 | 3 | 2 | 1,0 |
X | 0x00-0x02 | 0/1 | X | X | X |
而空的WILLTOPIC也是允许存在的,就两个字节表示,用于客户端请求删除已存在于服务器端的对应遗嘱主题和消息。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x02 |
1 | MsgType | 0x07 |
根据客户端CONNECT标志位中WILL字段为真情况下,网关向客户端发出遗嘱消息请求,格式如下:
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x02 |
1 | MsgType | 0x08 |
只有头部部分,没有别的。
客户端对网关WILLMSGREQ请求的响应,从而把遗嘱消息传递给网关进行保存。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x09 |
2-n | WillMsg | 客户端遗嘱 |
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x0A |
2-3 | TopicId | 客户端发出,此值为0x0000;服务器发出,需要包含对应于Topic Name的主题标识符 |
4-5 | MsgId | 自然数,用以标识对应的REGACK确认 |
6-n | TopicName | 主题名称,不能太长,尽量不要使用通配符 |
客户端或网关针对REGISTER消息的响应。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x07 |
1 | MsgType | 0x0B |
2-3 | TopicId | 对应于Topic Name的主题标识符,被用于PUBLISH消息发布 |
4-5 | MsgId | 自然数,用以标识对应的REGISTER消息 |
6 | ReturnCode | 0x00被接受,其它值被拒绝 |
PUBLISH消息用于客户端或网关发布消息用:
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x0C |
2 | Flags | 标志位 |
3-4 | TopicId | 主题标识符 |
5-6 | MsgId | QoS 1-2时需要填充自然值;QoS 0时,值为0x0000 |
7-n | Data | 用于发布的具体消息内容 |
标识位具体如下:
DUP | QoS | Retain | Will | CleanSession | TopicIdType |
---|---|---|---|---|---|
bit 7 | 6,5 | 4 | 3 | 2 | 1,0 |
0/1 | 0x00-0x02 | 0/1 | X | X | 0b00/0b01/0b10 |
标识位里面各个字段和MQTT协议一致,无须多解释。
客户端/网关仅仅对QoS 1/2的PUBLISH消息做出响应。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x07 |
1 | MsgType | 0x0D |
2-3 | TopicId | 对应PUBLISH消息中TopicId |
4-5 | MsgId | 自然数,用以标识对应的REGISTER消息 |
6 | ReturnCode | 0x00被接受,其它值被拒绝,不同值表示不同拒绝理由 |
处理PUBLISH消息异常?在PUBACK消息中的ReturnCode字段中以相应值体现出来,这就要求接收者处理拒绝理由。
只有在PUBLISH消息中QoS 2时,PUBREC, PUBREL, PUBCOMP才会一起登场,否则是没有出场机会的。消息格式嘛,都很统一:
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x04 |
1 | MsgType | 0x0F/0x10/0x0E |
2-3 | MsgId | 对应PUBLISH消息中的MsgId |
SUBSCRIBE用于客户端订阅某个主题的消息。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x12 |
2 | Flags | 标志位 |
3-4 | MsgId | 用于确定对应的订阅确认SUBACK消息 |
5-N | TopicId/TopicName | 具体需要根据Flags标志位中TopicIdType进行填充 |
标识位具体如下:
DUP | QoS | Retain | Will | CleanSession | TopicIdType |
---|---|---|---|---|---|
bit 7 | 6,5 | 4 | 3 | 2 | 1,0 |
0/1 | 0x00-0x02 | X | X | X | 0b00/0b01/0b10 |
此处,标志位中TopicIdType决定了SUBSCRIBE消息中TopicId/TopicName字段具体填充值:预定义topic id,或短小两个字符表示主题(topic name),或直接填写主题。
网关->客户端,订阅处理情况的确认回执,接受订阅或出于其它原因拒绝之。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x08 |
1 | MsgType | 0x13 |
2 | Flags | 标志位 |
3-4 | TopicId | 网关接受其注册,此处对应具体指派的TopicId |
5-6 | MsgId | SUBSCRIBE消息中对应MsgId值 |
7 | ReturnCode | 0x00被接受,其它值被拒绝 |
标识位具体如下:
DUP | QoS | Retain | Will | CleanSession | TopicIdType |
---|---|---|---|---|---|
bit 7 | 6,5 | 4 | 3 | 2 | 1,0 |
X | 0x00-0x02 | X | X | X | X |
SUBACK消息标志位中QoS为网关根据实际情况授权后的QoS具体值,这也应该是客户端需要知道并处理的。
UNSUBSCRIBE用于客户端取消订阅某个主题的消息。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x14 |
2 | Flags | 标志位 |
3-4 | MsgId | 用于确定对应的退订确认UNSUBACK消息 |
5-N | TopicId/TopicName | 具体需要根据Flags标志位中TopicIdType进行填充 |
标识位具体如下:
DUP | QoS | Retain | Will | CleanSession | TopicIdType |
---|---|---|---|---|---|
bit 7 | 6,5 | 4 | 3 | 2 | 1,0 |
X | X | X | X | X | 0b00/0b01/0b10 |
UNSUBSCRIBE消息标志位中唯一可用属性TopicIdType决定了UNSUBSCRIBE消息中TopicId/TopicName字段具体填充值。
网关->客户端,取消订阅处理情况的确认回执,很简单,4个字节表示。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x04 |
1 | MsgType | 0x15 |
2-3 | MsgId | UNSUBSCRIBE消息中对应MsgId值 |
和MQTT协议中的PINGREQ一致,存活检测。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x16 |
2-N | ClientId | 可选项,表示客户端休眠状态转换为唤醒状态用于检查网关是否为其缓存消息 |
接受PINGREQ消息的一方,如网关响应PINGRESP消息表示自己现在运行OK。
另外一个意图,若唤醒状态客户端发送PINGREQ消息之后,直接收到PINGRESP消息,表示网关当前暂时没有为其缓存的消息可供发送。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x02 |
1 | MsgType | 0x17 |
很简单,两个字节表示足矣。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x18 |
2-3 | Duration | 可选项,表示客户端即将进入睡眠状态的持续时间值 |
网关接收到要进入休眠状态的客户端发送的包含有Duration字段DISCONNECT消息时,可以直接返回2个字节的(不能包含有Duration字段)DISCONNECT消息以示确认。
客户端发送请求网关更新其遗嘱主题。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x1A |
2 | Flags | 标志位 |
3-N | WillTopic | 用于更新的遗嘱主题 |
标识位具体如下:
DUP | QoS | Retain | Will | CleanSession | TopicIdType |
---|---|---|---|---|---|
bit 7 | 6,5 | 4 | 3 | 2 | 1,0 |
X | 0x00-0x02 | 0/1 | X | X | X |
协议规定只有两个字节空WILLTOPICUPD也是允许存在的,存在意义用于客户端请求网关删除已保存的遗嘱主题和遗嘱消息等。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x02 |
1 | MsgType | 0x1A |
WILLTOPICRESP为网关收到WILLTOPICUPD后作出的应答消息。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x03 |
1 | MsgType | 0x1B |
2 | ReturnCode | 0x00被接受,其它值被拒绝 |
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 动态计算 |
1 | MsgType | 0x1C |
2-N | WillMsg | 用于更新的遗嘱消息 |
客户端->网关,确认更新的遗嘱消息。
WILLMSGRESP为网关收到WILLMSGUPD后作出的应答消息。
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 0x03 |
1 | MsgType | 0x1D |
2 | ReturnCode | 0x00被接受,其它值被拒绝 |
在MQTT-SN架构图中,MQTT-SN Forwarder转发器适用于客户端无法直接访问网关或当前传感器网络区域中不存在网关时,转发器作用就体现出来了:
转发器作用于消息的封装转发,解封发送,针对消息不做修改。
转发器对MQTT-SN消息封装格式:
字节索引 | 表示内容 | 说明 |
---|---|---|
0 | Length | 十进制表示长度就是N |
1 | MsgType | 0xFE |
2 | Ctrl | 包含网关和转发器之间的控制交换信息,主要是前两位包含了半径范围 |
3-N | Wireless Node Id | 标识所发目的或需要接收封装消息的无线节点 |
N+1-M | MQTT-SN message | 一个MQTT-SN消息消息 |
无线节点Id(Wireless Node Id):
控制交换字段Ctrl,单个字节,位表示含义:
bit 7,2 | 1,0 |
---|---|
X | 0x00-0x03 |
MQTT-SN 1.2规范中所定义消息格式介绍完毕,下一篇将对MQTT-SN主要流程功、能进行阐述。
原文 http://www.blogjava.net/yongboy/archive/2015/01/08/422142.html
标签:
原文地址:http://www.cnblogs.com/yudar/p/4642475.html