聂永的博客

记录工作/学习的点点滴滴。

MQTT-SN协议乱翻之小结篇

前言

这里简单做一些小结和对比,针对前面的协议翻译部分,一阶段的学习完结。

MQTT-SN VS MQTT

MQTT-SN基于MQTT原有语义,但做了很多的调整。比如: 一个CONNECT消息被拆分为3个消息 主题名称需要使用主题标识符替代 * 网关地址可以广播、查询得知

MQTT-SN 与 MQTT对比,使用一张图介绍

比较类型 MQTT MQTT-SN
传输类型 可靠点对点流模式 不可靠的数据报
通信方式 TCP/IP Non-IP 或 UDP
网络传输 Ethernet, WiFi, 3G ZigBee,Bluetooth,RF
最小消息 2个字节 2个字节
最大消息 ≤24MB < 128个字节
电池供电 X
休眠支持 X
QoS -1(哑客户端) X
主题标识符 X
网关自动发现和回退 X

QoS

有关QoS,MQTT-SN新增增加了哑客户端(QoS :-1)支持:

QoS Level 消息传输次数 传输语义 传输保证
-1 ≤ 1 至多一次 无连接,只用于传输,尽力而为,无保证;只有MQTT-SN支持
0 ≤ 1 至多一次 尽力而为,无保证
1 ≥ 1 至少一次 保证送达,可能存在重复
-1 ≡ 1 只有一次 保证送达,并且不存在重复

网关的查询和发现

  1. MQTT-SN客户端无须提前知道网关地址,接收网关的周期性广播好了,或直接广播一条网关查询;接收广播+主动查询,就够了
  2. MQTT-SN对客户端/网关的乱入和丢失,处理的很好,备用网关在主网关挂掉之后即可转换为主网关,针对客户端而言,直接更新一个新的网关地址就可以
  3. 存在的若干网关可以互相协调彼此之间角色,互为主备stand-by,出现问题,主机下线维护,从机升级主机

清理会话

和MQTT 3.1协议类似,在上一次的客户端成功连接时在CONNECT中设置了清理会话标志clean session为false,遗嘱特性Will也为true,再次连接时,那么服务器为其缓存订阅数据和遗嘱数据是否已经被删除,对客户端不透明,因为就算是服务器因内存压力等清理了缓存,但没有通知到客户端,会造成订阅、遗嘱的误解。

还好,MQTT-SN协议中,网关在清理掉遗嘱数据后,可以咨询客户端,或主动通知客户端断开,重新建立会话流程。

在MQTT 3.1.1协议中,服务器会在CONNACK中标记会话是否已经被持久的标记。

主题标识符(Topic id)

确切来说,MQTT-SN协议存在三种格式主题名称(topic name),可由消息标志位包含TopicIdType属性决定:

  • 0b01:预分配的主题标识符(topic id),16位自然数,0-65535范围
  • 0b10:预分配的短主题名称(short topic name),只有两个字符表示
  • 0b00:正常主题名称(topic name),可直接附加在REGISTER/SUBSCRIBE/WILLTOPICUPD消息对应字段中

所有主题被替换成标识符,在发布PUBLISH消息时,直接使用被指定的主题标识符topic id、short topic name即可。

MQTT-SN流程梳理

下面对MQTT-SN常用流程进行的流程简单梳理:

              Client              Gateway            Server/Broker
                |                   |                    |
Generic Process | --- SERCHGW ----> |                    |
                | <-- GWINFO  ----- |                    |
                | --- CONNECT ----> |                    |
                | <--WILLTOPICREQ-- |                    |
                | --- WILLTOPIC --> |                    |
                | <-- WILLMSGREQ -- |                    |
                | --- WILLMSG ----> | ---- CONNECT ----> |(accepted)
                | <-- CONNACK ----- | <--- CONNACK ----- |
                | --- PUBLISH ----> |                    |
                | <-- PUBACK  ----- | (invalid TopicId)  |
                | --- REGISTER ---> |                    |
                | <-- REGACK  ----- |                    |
                | --- PUBLISH ----> | ---- PUBLISH ----> |(accepted)
                | <-- PUBACK  ----- | <---- PUBACK ----- |
                |                   |                    |
                //                  //                   //
                |                   |                    |
 SUBSCRIBE   -->| --- SUBSCRIBE --> | ---- SUBSCRIBE --> |
 [var Callback] | <-- SUBACK ------ | <--- SUBACK ------ |
                |                   |                    |
                //                  //                   //
                |                   |                    |
                | <-- REGISTER ---- | <--- PUBLISH ----- |<-- PUBLISH
                | --- REGACK  ----> |                    |
[exec Callback] | <-- PUBLISH  ---- |                    |
                | --- PUBACK   ---> | ---- PUBACK  ----> |--> PUBACK
                |                   |                    |
                //                  //                   //
                |                   |                    |
active -> asleep| --- DISCONNECT -> | (with duration)    |
                | <-- DISCONNECT -- | (without duration) |
                |                   |                    |
                //                  //                   //
                |                   |                    |
                |                   | <--- PUBLISH ----- |<-- PUBLISH
                |                   | ----- PUBACK ----> |
                |                   | <--- PUBLISH ----- |<-- PUBLISH
                |                   | ----- PUBACK ----> |
                |                   | (buffered messages)|
asleep -> awake |                   |                    |
                | --- PINGREQ ----> |                    |
awake state     | <-- PUBLISH  ---- |                    |
                | <-- PUBLISH  ---- |                    |
                | <-- PINGRESP ---- |                    |
asleep <-awake  |                   |                    |

MQTT-SN运行的协议栈

MQTT-SN可以运行在不同的无线协议上,只要可以满足MQTT-SN 所定义即可:支持双向数据传输和网关即可,MQTT-SN完全可以运行在其上面。

MQTT-SN可以在ZigBee、Bluetooth、RF、UDP、6loWPAN等底层协议层面运行。

MQTT-SN网络拓扑图

下面是来自网友的基于MQTT-SN运行的架构图:

但实际上的其网络拓扑可能更为复杂,比如两个不同的传感器网络:

小结

传感器和制动器,合称为SA。传感器汇报状态数值(自身发布PUBLISH消息),制动器会被某参数值触发(接收到的PUBLISH消息)。好比,文件的输入-输出模式,传感器用于文件的读取,制动器用于文件写入。或者使用管道阀门,某指标超过阀值触发制动器报警,SA一起作用便于更好追踪数据。大部分时间,PUBLISH消息被用于触发制动器,这建立在后端服务器的分析结果基础上。

MQTT-SN比较知名的实现,比如(http://eclipse.org/proposals/technology.mosquitto/)[Eclipse Mosquitto],(RMSB)[http://git.eclipse.org/c/mosquitto/org.eclipse.mosquitto.rsmb.git/]等,但不是实现所有已定义细节,比如MQTT-SN协议转发部分(MQTT-SN Forwarder),就鲜有实现,但实现不难嘛,可能缺乏相应的场景支持吧。

MQTT-SN支持类似于传感器的网关,稍强的网络可与适用于MQTT协议,这样看来,MQTT要做到连接一切(Connect anything),如IBM所发布的红皮书所说,要使用MQTT打造一个智能星球,有戏!

posted on 2015-01-13 17:15 nieyong 阅读(9453) 评论(6)  编辑  收藏 所属分类: MQTT

评论

# re: MQTT-SN协议乱翻之小结篇 2015-01-13 17:20 涩兔子leslie

哈哈,发现老师也孤岛Arduino  回复  更多评论   

# re: MQTT-SN协议乱翻之小结篇[未登录] 2015-01-13 17:24 changedi

先赞一个,攒好货以后看~~  回复  更多评论   

# re: MQTT-SN协议乱翻之小结篇 2015-01-22 15:38 痘坑

好文章,当然要顶  回复  更多评论   

# re: MQTT-SN协议乱翻之小结篇 2015-01-28 09:17 mq

请问目前有开源的mqtt-sn代理吗  回复  更多评论   

# re: MQTT-SN协议乱翻之小结篇 2015-01-28 09:41 nieyong

@mq
请参考 Mosquitto,RMSB等  回复  更多评论   

# re: MQTT-SN协议乱翻之小结篇 2015-01-28 09:50 mq

@nieyong
mosquitto目前还不支持
RSMB没有试成功过  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

公告

所有文章皆为原创,若转载请标明出处,谢谢~

新浪微博,欢迎关注:

导航

<2015年1月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

常用链接

留言簿(58)

随笔分类(130)

随笔档案(151)

个人收藏

最新随笔

搜索

最新评论

阅读排行榜

评论排行榜