MQTT是基于二进制消息的发布/订阅编程模式的消息协议。本文主要介绍mqtt功能,不涉及具体协议分析。因为一般情况下,使用mqtt都是用相应库,使用时需要弄懂相应参数指标并参考库API使用即可。如果涉及具体需求带着目的去看协议效率更高。
MQTT协议文档:http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
文章目录
1 MQTT协议特点
基于TCP
标准协议支持(无锁定)
长连接、双向的消息Pub/Sub 代理
Http相比具有较强的性能优势
1.1 无锁定特性
发布/订阅模式解耦了发布消息的客户(发布者)与订阅消息的客户(订阅者)之间的关系,这意味着发布者和订阅者之间并不需要直接建立联系。
- 发布者与订阅者不必了解彼此,只要认识同一个消息代理即可。
- 发布者和订阅者不需要交互,发布者无需等待订阅者确认而导致锁定。
- 发布者和订阅者不需要同时在线,可以自由选择时间来消费消息。
1.2 长连接、双向的消息Pub/Sub 代理
通信方式灵活具有多种模式。
点对点模式:
多个点对点:
广播模式:
聚合模式:
1.3 http相比具有较强的性能优势
- 吞吐量速度提升93
- 接收信息需要的电池降低170.9 倍
- 保持连接需要的电源降低50%
- 网络开销降低8 倍
数据来源:http://stephendnicholas.com/archives/1217
2 MQTT中基础概念
MQTT功能实现是通过协议14种不同数据包实现,包括CONNECT, PUBLISH,SUBSCRIBE等类型数据包。但如果我们实现SDK就不用关心具体数据包的封装及实现。我们需要了解的即为以下几个功能概念。至于如何使用可参考1.2中几种模式,连入同一个mqtt服务器,以相同消息通信,一方订阅,一方推送即可。
控制报组成:http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
2.1 主题(topic)
主题是附加到应用程序消息的标签,该标签与服务器已知的预订相匹配。服务器将应用程序消息的副本发送到具有匹配订阅的每个客户端。MQTT是通过主题对消息进行分类的,本质上就是一个UTF-8的字符串,不过可以通过反斜杠表示多个层级关系。通信双方通过相同的topic进行通信,即订阅发布。
2.2 消息负载(payload)
消息中消息体内容,因为mqtt协议限制每个数据包最大容量为256MB
2.3 服务质量(QOS)
作用:保证消息到达。
为了满足不同的场景,MQTT支持三种不同级别的服务质量(Quality of Service,QoS)为不同场景提供消息可靠性:
级别0:尽力而为。消息发送者会想尽办法发送消息,但是遇到意外并不会重试。
级别1:至少一次。消息接收者如果没有知会或者知会本身丢失,消息发送者会再次发送以保证消息接收者至少会收到一次,当然可能造成重复消息。
级别2:恰好一次。保证这种语义肯定会减少并发或者增加延时,不过丢失或者重复消息是不可接受的时候,级别2是最合适的。
2.4 消息持久性(Retain )
作用:服务器存储消息,推送给未来的订阅者。
Retain 持久消息(粘性消息)
RETAIN 标记:每个Publish消息都需要指定的标记
0 —— 服务端不能存储这个消息,也不能移除或替换任何 现存的保留消息
1 —— 服务端必须存储这个应用消息和它的QoS等级,以便它可以被分发给未来的订阅者
每个Topic只会保留最多一个 Retain 持久消息
客户端订阅带有持久消息的Topic,会立即受到这条消息
服务器可以选择丢弃持久消息,比如内存或者存储吃紧的时候
如果客户端想要删除某个Topic 上面的持久消息,可以向这个Topic发送一个Payload为空的持久消息
遗嘱消息(Will)的Retain持久机制同理
2.5 长连接维护与管理(keep alive)
作用:设备如果在一定时间内不与server通信,server就会断开链接。
Keep Alive 心跳 :
目的是保持长连接的可靠性,以及双方对彼此是否在线的确认。
客户端在Connect的时候设置 Keep Alive 时长。如果服务端在 1.5 * KeepAlive 时间内没有收到客户端的报文,它必须断开客户端的网络连接
Keep Alive 的值由具体应用指定,一般是几分钟。允许的最大值是 18 小时 12 分 15 秒
2.6 遗嘱(Will)
作用:处理server异常离线情况,获取设备是否在线。
遗嘱消息(Will Message)存储在服务端,当网络连接关闭时,服务端必须发布这个遗嘱消息,所以被形象地称之为遗嘱,可用于通知异常断线。注意遗嘱也是消息,消息该有的属性都有。
客户端发送 DISCONNECT 关闭链接,遗嘱失效并删除遗嘱消息发布的条件,包括:
服务端检测到了一个 I/O 错误或者网络故障
客户端在保持连接(Keep Alive)的时间内未能通讯
客户端没有先发送 DISCONNECT 报文直接关闭了网络连接
由于协议错误服务端关闭了网络连接
相关设置项,需要在Connect时,由客户端指定
Will Flag —— 遗嘱的总开关
0 – 关闭遗嘱功能,Will QoS 和 Will Retain 必须为 0
1 – 开启遗嘱功能,需要设置 Will Retain 和 Will QoS
详细协议可参考:https://blog.csdn.net/u011216417/article/details/69666752
3 Sample
原来在stm32 上实现过mqtt client。 server使用mosquitto。
现在是直接使用AWS IOT 功能,所以不当好搭建sample,进行每一步说明。可参考这篇AWS IOT 使用文章进行理解
4 参考链接
基于AWS IoT平台的物联网解决方案(张春涛(Michael Zhang),AWS解决方案架构师 2016年6月6日)
http://blog.csdn.net/u011216417/article/details/69666752
http://dataguild.org/?p=6817