mqtt协议 学习笔记
文章目录
- 1. MQTT协议介绍
- 2. MQTT协议特性
- 3. MQTT协议的通信模型
- 3. MQTT的主题
- 4. MQTT协议的连接与会话
- 5. MQTT 报文格式
- 5.1 报文类型汇总
- i. 连接报文
- 连接报文的用户名和密码
- 连接报文的遗嘱消息
- ii. 订阅报文
- iii. 发布报文
- 5.2 Qos级别
1. MQTT协议介绍
MQTT(Message Queuing Telemetry Transport)消息队列遥测传输
Telemetry 表面MQTT协议 适合于 遥测数据的传输,,如遥测数据的上传,制动命令下发等等。
mqtt 由IBM 提出,发布的是MQTT V3.1版本。在2014年,被OASIS采用,发布了MQTT V3.1.1版本。现在MQTT还是有OASIS维护和开发。
MQTT 协议中,有三类对象。分别是:订阅者,发布者,消息代理(服务器)
2. MQTT协议特性
- 轻量级协议,开销小
适用于M2M(machine to machine),WSN(wireless sensor network),Iot。
14种类型消息 - 异步通信模式,解耦通信双方
空间解耦,通信双方不需要知道对方的IP地址和端口号。
时间解耦,通信双方不需要同时在线。(使用topic 把双方联系起来) - 基于TCP
MQTT是应用层的协议,是基于TCP协议的。
3. MQTT协议的通信模型
MQTT 应用于M2M(机器节点与机器节点之间)的通信,两个机器之间不需要知道对方的IP地址和端口号,只需要 接收/发送 服务器(消息代理)的数据就行。所以MQTT中有两种角色:MQTTCLient、MQTTServer
- MQTTClient MQTT客户端
MQTTClient 一般是我们的传感器节点/制动器节点。主要是往 MQTT Server 发布消息,订阅消息,并且接收之后MQTT Server 发送过来的订阅消息。
MQTT客户端可以说发布者,也可以是订阅者,取决于应用逻辑。例如:stm32节点需要往MQTT服务器发布消息,上传传感器数据,故stm32是发布者;同时stm32也需要订阅服务器的消息,接收服务器发送的消息,故stm32也是订阅者。 - MQTT Server MQTT服务端
服务端工作主要是 Topic主题队列维护、消息的队列维护、消息的转发。
接收客户端的主题订阅,并转发该主题下的消息到对应的客户端。- Topic主题:可以理解为 消息的种类
- 消息:就是具体的消息内容
以一个智能家居系统为例子,我们把 客厅温度 作为一个 Topic主题;客厅温度传感器连接到MQTT server服务器,往 客厅温度 这个Topic主题发布温度数据消息。;然后手机APP作为客户端,订阅客厅温度这个主题,这是服务器就会把接收到的客厅温度传感器的温度数据消息转发到所有订阅了客厅温度这个Topic主题的客户端。
3. MQTT的主题
4. MQTT协议的连接与会话
·连接由客户端发起,会建立一个会话,把客户端附着到服务器上
·服务器根据连接参数(ClientID,用户名,密码)对客户端进行鉴权和授权
·连接参数(CleanSession)决定此次会话是否是持久会话(Persistent Session)
检测心跳
在心跳间隔中如果没有数据交互,需要发送心跳报文保活连接,否则连接将会断开.会话保持 Clean Session:
对应客户端:略
对于服务端:是否保存此次连接中,客户端订阅的主题.
如果客户端中的连接报文中,CleanSession 设置为0,服务端会保存此次客户端订阅的所有主题,连接断开后,仍然保存订阅的消息.在客户端下线后,如果服务端接收到这些主题的消息,服务器会保存这些主题的消息,在客户端上线后,再往客户端推送这些消息.
5. MQTT 报文格式
·固定报头,2~5字节,所有报文都包含。
·可变报头,长度不固定,部分报文才包含
·有效负载,长度不固定,部分报文才包含
5.1 报文类型汇总
MQTT中有 14中 报文类型
i. 连接报文
在绿色的可变报头中就包含了需要连接信息的标识,这些标识flag决定了有效负载的内容(如:有效负载中是否有遗嘱,遗嘱信息,用户名,密码)\此次连接的心跳间隔等等.
连接报文的用户名和密码
连接报文的遗嘱消息
遗嘱消息是客户端连接服务端时,告诉服务端的消息.所以在连接报文中有几个与遗嘱消息相关的参数,这几个参数是客户端对遗嘱消息的描述.
服务端接收到遗嘱消息后,先会把遗嘱消息保存起来.如果客户端意外断开连接,服务端会把遗嘱消息转发到所有订阅了此遗嘱消息主题的其他客户端.
服务端会一直保存遗嘱消息,直到客户端发送DISCONNECT 类型的消息才会删除此遗嘱消息.
遗嘱消息不是必须的,取决一个客户端连接保证中的 Will Flag 是否置位.
遗嘱消息也会有retain属性,发布和转发的Qos级别.
ii. 订阅报文
- TopicName
订阅操作的对象是某个主题,可以是一个或多个主题. - Qos Level
服务器记录了该订阅的消息,当有该主题的消息到来后,服务器会以设置好的Qos级别来转发消息.这里的Qos是用于服务端到客户端下行转发数据的Qos级别.
因为一次订阅操作可以订阅多个主题,与订阅主题的Qos也可以不一样,因此Qos这个域不是在订阅报文的固定报头,而是紧紧的跟随在主题名之后
iii. 发布报文
发布操作的对象是某个主题的消息.因此发布报文中重要的参数就是主题名称和消息负载
发布报文的QosLevel 是作用于客户端到服务端消息上行的过程
5.2 Qos级别
在订阅报文和发布报文中,MQTT 协议中定义了三种报文的服务质量
- Qos0
发送方只发送一次消息,不管对方是否接收到消息.接收方接收到消息后也不用回应(这里的发送方可以是客户端,也可以是服务端)
发送的消息质量完全由,TCP/IP 网络决定,如果发送工程中,TCP连接断开,数据就会丢失
应用场景是传感器数据的定时发送,个别数据的丢失,对于应用来说不是关键的问题,一般应用都会对一段时间的数据进行整合处理:如取平均值 - Qos1
发送方要保证接收方一定接收到了消息,所有接收方要回应一个PUBACK的报文应答.
如果发送方没有接收到PUBACK的报文应答,就会再次发送消息,接收方会受到两次消息
应用场景:门开关的状态传感器-门的开关状态一定要无遗失的告诉订阅者,重复的消息可以通过msgId来过滤丢弃. - Qos2
带来最大的协议开销
## Re
如上图,默认发布和订阅的消息都是同一个主题.
客户端1 发布retain=0的消息(灰色),客户端2在发布消息之后才向服务端订阅消息,服务端不会转发客户端1上次发布的消息(灰色)
只有在客户端1 再次发布消息(绿色)时,客户端2才能接收到客户端1发布的消息
客户端1发布retain=1的消息(黄色),服务器会保存该发布的数据和Qos等级
客户端3 在客户端1发布消息之后才向服务端订阅消息,这时服务端会往客户端3转发客户端1上次发布的消息(黄色)
客户端1 再次发布retain=1的消息(浅绿色),服务器会转发此发布消息,并且保存该发布的数据和Qos等级,丢弃上一个保存的retain=1的消息.