1. MQTT简介
MQTT是一种基于客户端服务端架构的发布/订阅模式的消息传输协议。他的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得他对很多场景来说都是很好的选择,尤其是对于受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT)。
MQTT特点
- 消息模式:发布/订阅消息模式,提供一对多的消息发布;
- 可靠传输:MQTT是基于TCP连接进行数据推送的;
- 服务等级:支持QoS等级,根据消息的重要性设置不同的服务等级;
- 轻量级:小型传输,开销很小,协议交换最小化,以降低网络流量;
- 遗嘱机制:使用will遗嘱机制来通知客户端异常断线;
- 主题机制:基于主题发布/订阅消息,对负载内容屏蔽的消息传输。
MQTT版本
一共是两个主流版本,一个是V3.1.1,另一个是升级版V5。
MQTT5实在MQTT3.1.1的基础上进行了升级,所以MQTT5是完全兼容MQTT3.1.1的。
MQTT协议重要角色
- 服务端(broker):MQTT信息传输的枢纽,负责数据传递和客户端管理,确保客户端之间的通讯顺畅;(一般是云端)
- 客户端(Client):“发布”——向服务器发布消息,“订阅”——从服务器收取信息;(有点类似微博的机制,只有关注了该主题,才能获取该主题信息)
客户端的发布和订阅都是围绕“主题”来进行的!!!
同时客户端可以是订阅者也可以是发布者!!!
电脑端订阅了主题“C”,所以在开发板发送了主题“C”的数据之后,电脑端能够接收到信息;而手机端没有订阅,所以不会有接收。
MQTT发布/订阅特性
- 相互独立:MQTT客户端相互独立,依然可以实现信息交流
- 空间分离:MQTT客户端和MQTT服务端处于同一个通信网络中
- 时间异步:MQTT客户端在发送和接收消息时无需同步
QoS服务质量
服务质量是MQTT的一个重要特性。
当我们使用TCP/IP协议时,连接已经在一定程度上受到保护;但是再无线网络中,中断和干扰很频繁,MQTT在这里帮助避免信息丢失及其服务质量水平。这些级别在发布时使用。
报文在不可靠的信道上可能存在丢失,于是最直接的解决方案就是重发;服务质量实际就是表示报文要发布几次:
- QoS 0:最多一次 <=1;
- QoS 1:至少一次 >=1;
- QoS 2:一次 =1。
QoS0服务质量
发送端一旦发送完消息,就完成任务。发送端不会检查发送的消息能否被正确接收到。(类似UDP)
QoS1服务质量
发送端在消息发送完成后,会检查接收端是否已经成功接收到消息。
如果服务端没有返回一个应答的ACK包,就会再次发送报文,直到有接收到应答信号。
QoS2服务质量
发送端需要接收端进行两次消息确认,所以2级MQTT服务质量是最安全的服务级别,也是最慢的服务等级。
2. MQTT协议报文结构
固定报头是一定存在的,表示数据包类型以及数据包的标识,最少也会有2个字节;而可变包头和有效负载是可选的,都是根据数据包的类型来决定的。
固定报头
固定报头至少2个字节,第1个字节中:
高4位:报文类型;低4位:报文类型相关标志位;
第2个字节以及之后字节(至多4个字节)是剩余数据的长度。
一共14种报文类型;
CONNECT就是客户端发送到服务端的,表示客户端请求连接服务器;CONNACK是服务端发给客户端的,表示服务端连接报文的确认应答信号;
PUBLISH就是发布消息,如果是QoS1就会有PUBACK应答信号表示发布确认;如果是QoS2,那么会有PUBREC发布收到,PUBREL发布释放以及PUBCOMP发布完成信号;
SUBSCRIBE是客户端发送给服务端的,是一个客户端订阅的请求信号;SUBACK就是服务端发回客户端的服务端订阅确认信号;UNSUBSCRIBE和UNSUBACK就是取消订阅相关信号;
PINGREQ是客户端发给服务端的客户端心跳请求信号,PINGRESP就是服务端的心跳响应信号;
最后还有一个DISCONNECT的客户端发给服务端的断开连接信号。
在PUBLISH中,在MQTT3.1.1版本中用到了如下3中标志:
- DUP:PUBLISH报文的重复传送标志;
- QoS:PUBLISH报文的服务质量等级;
- RETAIN:PUBLISH报文的保留标志。
这其中,DUP有如下参数:
- 0:客户端/服务端第一次尝试发送PUBLISH数据包;
- 1:可对之前尝试发送的数据包重新发送。
当客户端或服务端尝试重新传递PUBLISH数据包,DUP必须是1;所有的QoS0消息,DUP必须是0。
MQTT可变报头
某些类型的MQTT控制数据包包含可变报头,它位于固定报头和有效负载之间。可变报头的内容根据报文类型决定。例如:CONNECT报文的可变报头有:协议名、协议等级、连接标志和保活间隔等部分。可变报头的报文标识符在几种数据包类型中是通用的。
MQTT有效负载
有些MQTT控制报文在数据包的最后部分包含有效负载,例如对PUBLISH报文来说,有效负载就可以是应用消息。
包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息需要有效负载:
- CONNECT:客户端ID、订阅的Topic、Message以及用户名和密码;
- SUBSCRIBE:订阅的Topic以及QoS;
- SUBACK:服务端对于SUBSCRIBE所申请的Topic以及QoS进行确认和回复;
- UNSUBSCRIBE:取消订阅的Topic。
这四种是必须要Payload的,而PUBLISH是可选择是否需要的。
3. MQTT原理解析
- 客户端与代理服务器建立连接
首先要通过TCP与代理服务器建立连接,这就需要代理服务器的IP地址和端口号;然后通过MQTT的库配置账号密码还有各种参数,然后调用CONNECT方法请求连接;服务端是一直监听的,建立了TCP连接并接收到CONNECT报文后,会进行数据解析并配置参数,之后发送CONNACK的应答信号;客户端收到信号后解析并成功连接,就进入订阅主题的步骤。
- 客户端向代理服务器订阅
通过MQTT的库,通过Subscribe方法发送SUBSCRIBE报文给服务端;服务端解析报文后,会记录客户端的订阅主题,发送SUBACK报文给客户端;客户端接收到应答信号后,就会解析报文并成功订阅,之后监听代理服务器的主体信息。
- 客户端向代理服务器发布主题
调用MQTT的API来构建发布报文,然后发送PUBLISH报文;服务器解析发送报文,会发送PUBACK返回客户端;客户端解析后,会监听服务器消息;服务器会根据QoS查找相应客户端,找到符合条件的客户端之后,会推送同主题的消息;本客户端就会这样收到订阅消息。
总结
MQTT是很常用的应用层协议,物联网这边很多都是用MQTT完成的联网工作,这一篇主要学习了一下MQTT的命令种类以及相关的数据传输流程。