前言

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

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打造一个智能星球,有戏!

原文 http://www.blogjava.net/yongboy/archive/2015/01/13/422207.html

MQTT-SN协议乱翻之小结篇的更多相关文章

  1. MQTT-SN协议乱翻之功能描述

    前言 紧接上文,这是第三篇,主要是对MQTT-SN 1.2协议进行总体性功能描述. 嗯,这一部分可以结合着MQTT协议对比着来看. 网关的广播和发现 网关只能在成功连接到MQTT Server之后,才 ...

  2. MQTT-SN协议乱翻之消息格式

    前言 紧接着上篇初步介绍,本文为第二篇,主要梳理MQTT-SN 1.2协议中定义的消息格式. 通用消息格式 消息头 其它可变部分 2/4字节表示 N字节组成 消息头部 长度 消息类型 1或3个字节 1 ...

  3. MQTT-SN协议乱翻之简要介绍

    前言 这一段时间在翻看MQTT-SN的协议,对针对不依赖于TCP传输的MQTT协议十分感兴趣,总是再想着这货到底是怎么定义的.一系列文章皆有MQTT-SN 1.2协议所拼装组成,原文档地址: MQTT ...

  4. MQTT-SN协议乱翻之实现要点

    前言 本篇是MQTT-SN 1.2协议最后一篇翻译了,主要涉及实现要点,很简短. 需要支持QoS 值为 -1 QoS虽默认设置有0,1,2三个值,但还有一种情况其值为-1.来自客户端的PUBLISH消 ...

  5. 基于GBT28181:SIP协议组件开发-----------第四篇SIP注册流程eXosip2实现(一)

    原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3945294.html. 上章节讲解了利用自主开发的组件SIP组件l ...

  6. TCP协议详解(理论篇)

    TCP协议详解(理论篇) 2012-08-20      0个评论       作者:陈立龙 收藏    我要投稿 TCP协议详解(理论篇)   1.    与UDP不同的是,TCP提供了一种面向连接 ...

  7. 物联网时代-跟着Thingsboard学IOT架构-MQTT设备协议

    Thingsboard的MQTT设备协议 thingsboard官网: https://thingsboard.io/ thingsboard GitHub: https://github.com/t ...

  8. IOT设备通讯,MQTT物联网协议,MQTTnet

    一.IOT设备的特性 硬件能力差(存储能力基本只有几MB,CPU频率低连使用HTTP请求都很奢侈) 系统千差万别(Brillo,mbedOS,RIOT等) 如使用电池供电,电量消耗敏感 如果是小设备, ...

  9. 小程序入门 MQTT物联网协议 publish 和订阅subscribe onenet 阿里云 百度云 基于GPRS模块(SIM800C/SIM900A/SIM868等)和STM32主控芯片

    本文基本公开了如何移植MQTT物联网协议到STM32平台上,并结合GPRS模块(SIM800C/SIM900A/SIM868等)实现publish和订阅topic从onenet,阿里云,百度云等.如果 ...

随机推荐

  1. buildroot 搭建ftpd 服务器记录

    vsftpd 搭建失败,应该是buildroot 文件系统还有操作没有理解透,还需要不断的学习. 所以用轻量级的 ftpd 进行替代, 步骤如下: // ---> make busybox-me ...

  2. [镜像]loop设备及losetup命令介绍

    最近需要对一个镜像文件进行修改,可以些方式是通过losetup和kpartx, mount完成,于是分享下面这篇 转自:http://blog.csdn.net/ustc_dylan/article/ ...

  3. 解析:SO_REUSEADDR bind: address in use

    http://blog.sina.com.cn/s/blog_53a2ecbf010095db.html socket中的SO_REUSEADDR Q: 我正在写一个unix server程序,不是d ...

  4. oracle 字符集 AL32UTF8、UTF8

    简介:ORACLE数据库字符集,即Oracle全球化支持(Globalization Support),或即国家语言支持(NLS)其作用是用本国语言和格式来存储.处理和检索数据.利用全球化支持,ORA ...

  5. Mac下面的SecureCRT(附破解方案) 更新到最新的7.2的破解方案

    继续更新到7.2的破解.只是升级了下secureCRT到7.2,方法还是不变 相信很多人升级到了7.2的SecureCRT之后原来的破解方案失效了,一直也有人问新的破解方案,发现了,不敢独享放上crt ...

  6. Web API(一);Restful架构

    一.什么是RESTful REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移.REST指的是一组架构约束条件和原则.如果一个 ...

  7. BuddyPress创建组、查看成员信息等找不到页面

    BuddyPress创建组.查看成员信息等找不到页面 http://aoxuangame.com/wordpress/groups/create/ http://aoxuangame.com/word ...

  8. PHP框架之ThinkPHP项目CMS内容管理系统源码及开发手册视频

    http://download.csdn.net/download/duguqing/4203042

  9. CSS编写指导规范和建议

    在参与规模庞大.历时漫长且参与人数众多的项目时,所有开发者遵守如下规则极为重要: 保持 CSS 易于维护 保持代码清晰易懂 保持 CSS 的可拓展性 为了实现这一目标,我们要采用诸多方法. 本文档第一 ...

  10. 【转】【C++】C++ 中的线程、锁和条件变量

    线程 类std::thread代表一个可执行线程,使用时必须包含头文件<thread>.std::thread可以和普通函数,匿名函数和仿函数(一个实现了operator()函数的类)一同 ...