前言
MQTT (Message Queue Telemetry Transport)是一种基于发布/订阅(publish/subscribe)模式的轻量级通讯协议,通过订阅相应的主题来获取消息,是物联网(Internet of Thing)中的一个标准传输协议。
该协议将消息的发布者(publisher)与订阅者(subscriber)进行分离,因此可以在不可靠的网络环境中,为远程连接的设备提供可靠的消息服务,使用方式与传统的 MQ 有点类似。

TCP 协议位于传输层,MQTT 协议位于应用层,MQTT 协议构建于 TCP/IP 协议上,理论上,只要支持 TCP/IP 协议栈的地方,都可以使用 MQTT 协议。
协议优势
MQTT 协议在物联网(IOT)中非常流行,主要有几点:
HTTP协议它是一种同步协议,客户端请求后需要等待服务器的响应。而在物联网(IOT)环境中,设备会很受制于环境的影响,比如带宽低、网络延迟高、网络通信不稳定等,显然异步消息协议更为适合IOT应用程序。HTTP是单向的,如果要获取消息客户端必须发起连接,而在物联网(IOT)应用程序中,设备或传感器往往都是客户端,这意味着它们无法被动地接收来自网络的命令。- 通常需要将一条命令或者消息,发送到网络上的所有设备上。
HTTP要实现这样的功能不但很困难,而且成本极高。
协议结构
MQTT是一种轻量级的协议,它只专注于发消息, 所以此协议的结构也比较简单。
MQTT数据包
在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、 可变头(Variable header)、 消息体(payload)三部分构成。

- 固定头(
Fixed header),所有数据包中都有固定头,包含数据包类型及数据包的分组标识。 - 可变头(
Variable header),部分数据包类型中有可变头。 - 消息体(
Payload),存在于部分数据包类,是客户端收到的具体消息内容。
固定头
固定头 存在于所有 MQTT 数据包中,使用两个字节,共16位,结构如下:
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | MQTT数据包类型 | 不同类型MQTT数据包的具体标识 | ||||||
| byte 2… | 剩余长度 |
4-7位表示消息类型,使用 4 位二进制表示,可代表如下的16种消息类型,不过 0 和 15位置属于保留待用,所以共14种消息事件类型。
| 名称 | 值 | 流方向 | 描述 |
|---|---|---|---|
| Reserved | 0 | 不可用 | 保留位 |
| CONNECT | 1 | 客户端到服务器 | 客户端请求连接到服务器 |
| CONNACK | 2 | 服务器到客户端 | 连接确认 |
| PUBLISH | 3 | 双向 | 发布消息 |
| PUBACK | 4 | 双向 | 发布确认 |
| PUBREC | 5 | 双向 | 发布收到(保证第1部分到达) |
| PUBREL | 6 | 双赂 | 发布释放(保证第2部分到达) |
| PUBCOMP | 7 | 双向 | 发布完成(保证第3部分到达) |
| SUBSCRIBE | 8 | 客户端到服务器 | 客户端请求订阅 |
| SUBACK | 9 | 服务器到客户端 | 订阅确认 |
| UNSUBSCRIBE | 10 | 客户端到服务器 | 请求取消订阅 |
| UNSUBACK | 11 | 服务器到客户端 | 取消订阅确认 |
| PINGREQ | 12 | 客户端到服务器 | PING请求 |
| PINGRESP | 13 | 服务器到客户端 | PING应答 |
| DISCONNECT | 14 | 客户端到服务器 | 中断连接 |
| Reserved | 15 | 不可用 | 保留位 |
DUP Flag(重试标识)
DUP Flag:保证消息可靠传输,消息是否已送达的标识。默认为0,只占用一个字节,表示第一次发送,当值为1时,表示当前消息先前已经被传送过。
QoS Level(消息质量等级)
QoS Level:消息的质量等级
RETAIN(持久化)
- 值为
1:表示发送的消息需要一直持久保存,而且不受服务器重启影响,不但要发送给当前的订阅者,且以后新加入的客户端订阅了此Topic,订阅者也会马上得到推送。注意:新加入的订阅者,只会取出最新的一个RETAIN flag = 1的消息推送。 - 值为
0:仅为当前订阅者推送此消息。
Remaining Length(剩余长度)
- 在当前消息中剩余的
byte数,包含可变头部和消息体payload。
可变头
固定头部仅定义了消息类型和一些标志位,一些消息的元数据需要放入可变头部中。可变头部内容字节长度 + 消息体payload = 剩余长度。
可变头部居于固定头部和payload中间,包含了协议名称,版本号,连接标志,用户授权,心跳时间等内容。
可变头存在于这些类型的消息:
PUBLISH (QoS > 0)PUBACKPUBRECPUBRELPUBCOMPSUBSCRIBESUBACKUNSUBSCRIBEUNSUBACK
消息体
消息体 payload 只存在于 CONNECT、PUBLISH、SUBSCRIBE、SUBACK、UNSUBSCRIBE 这几种类型的消息:
CONNECT:包含客户端的ClientId、订阅的Topic、Message以及用户名和密码。PUBLISH:向对应主题发送消息。SUBSCRIBE:要订阅的主题以及QoS。SUBACK:服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。UNSUBSCRIBE:取消要订阅的主题。
消息质量(QoS)
消息的发送质量,发布者(publisher)和订阅者(subscriber)都可以指定 qos 等级,有三个等级:
QoS 0QoS 1QoS 2
QoS 0
At most once(至多一次)只发送一次消息,不保证消息是否成功送达,没有确认机制,消息可能会丢失或重复。
具体流程

QoS 1
At least once(至少一次),相对于 QoS 0 而言 Qos 1 增加了 ack 确认机制,发送者(publisher)推送消息到MQTT代理(broker)时,两者自身都会先持久化消息,只有当publisher 或者 Broker分别收到 PUBACK确认时,才会删除自身持久化的消息,否则就会重发。
虽然可以通过确认来保证一定收到客户端 或 服务器的 message,可却不能保证只收到一次 message,当客户端publisher没收到Broker的puback或者 Broker没有收到subscriber的puback,那么就会一直重发。
具体流程
publisher store msg->publish->broker(发送 message)broker->puback->publisher delete msg(确认回执)

QoS 2
Exactly once(只有一次),相对于QoS 1,QoS 2升级实现了仅接受一次message,publisher 和 broker 同样对消息进行持久化,其中 publisher 缓存了message和 对应的 msgId,而 broker 缓存了 msgId,可以保证消息不重复,由于又增加了一个confirm 机制,整个流程变得复杂很多。
具体流程:
publisher store msg->publish->broker->broker store(发送消息)msgId(传递 message)broker->puberc(确认传递成功)publisher->pubrel->broker delete msgId(通知broker删除msgId)broker->pubcomp->publisher delete msg(通知publisher删除msg)

最后遗嘱(LWT)
LWT 全称为 Last Will and Testament,遗嘱是一个由客户端预先定义好的主题和对应消息,附加在CONNECT的数据包中,包括遗愿主题、遗愿 QoS、遗愿消息等。
当MQTT代理 Broker 检测到有客户端client非正常断开连接时,再由服务器主动发布此消息,然后相关的订阅者会收到消息。
遗嘱的相关参数:
Will Flag:是否使用LWT,1 开启Will Topic:遗愿主题名,不可使用通配符Will Qos:发布遗愿消息时使用的QoSWill Retain:遗愿消息的Retain标识Will Message:遗愿消息内容
客户端非正常断开连接的场景
Broker检测到底层的I/O异常;- 客户端 未能在心跳
Keep Alive的间隔内和Broker进行消息交互; - 客户端 在关闭底层
TCP连接前没有发送DISCONNECT数据包; - 客户端 发送错误格式的数据包到
Broker,导致关闭和客户端的连接等。
当客户端通过发布 DISCONNECT 数据包断开连接时,属于正常断开连接,并不会触发 LWT 的机制,与此同时Broker 还会丢弃掉当前客户端在连接时指定的相关 LWT 参数。
中间件
MQTT 是一种协议,支持MQTT协议的消息中间件产品有很多,比如
RabbitMQApache ActiveMQHiveMQApache Apolloemqttd Xively
应用场景
MQTT 协议广泛应用于物联网、移动互联网、智能硬件、车联网、电力能源等领域。
最后
以上就是俊秀老师最近收集整理的关于MQTT协议的全部内容,更多相关MQTT协议内容请搜索靠谱客的其他文章。
发表评论 取消回复