MQTT:Message Queuing Telemetry Transport,消息队列遥测传输,一种基于TCP/IP协议族的应用层协议。该协议是专门针对硬件性能低下&网络状况不稳定的场景设计,这使得MQTT在物联网和移动应用等受限场景有广泛应用。
MQTT是基于发布订阅模型的协议,因其带宽消耗小而被广泛用于物联网协议
HTTP/2 是 HTTP/1.x 的升级,主要体现在:利用 “多路复用和二进制分帧” 来解决队首阻塞问题,降低了通信时延;利用 “头部压缩” 减少消息头部,降低了传输开销;实现了 服务器推送,允许在不发起请求的情况下将数据推送到客户端,弥补了 Http/1.x 依赖 Websockets 才能实现推送的缺陷。这些改进使得 HTTP/2 也具有适应物联网场景的条件。随着HTTP/2成为标准,对websockets的需求可能会下降
对比MQTT、WebSocket、HTTP/2,我们从带宽、轻便方面考虑会选择MQTT协议
该协议操作的元素是二进制数据而不是文本数据。所以MQTT是一种基于二进制的协议,消息头最小只需要2字节,最多只需要5字节
MQTT消息结构 | 描述 | 长度 |
---|---|---|
固定报头(Fixed header) | 存在于所有MQTT消息中 | 2~5 字节 |
可变报头(Variable header) | 存在于部分MQTT消息中 | 0~N 字节 |
载荷(Payloads) | 存在部分MQTT消息中 | 0~N 字节 |
可对比TCP报头一起理解。mqtt固定报头最少2字节:
剩余长度本身包含1个字节,用于标识剩余的3个字节(可变报头、载荷)
控制报文类型与标志位罗列:
控制报文类型 | 标志位 | 描述 |
---|---|---|
Reserved | 0 | 保留字段 |
CONNECT | 1 | 客户端请求连接服务器 |
CONNACK | 2 | Connect消息确认 |
PUBLISH | 3 | 客户端发布消息 |
PUBACK | 4 | Publish消息确认(QoS1) |
PUBREC | 5 | 发布收到(保证交付第一步) |
PUBREL | 6 | 发布释放(保证交付第二步) |
PUBCOMP | 7 | 发布完成(保证交付第三步) |
SUBSCRIBE | 8 | 客户端订阅消息 |
SUBACK | 9 | SUBSCRIBE 消息确认 |
UNSUBSCRIBE | 10 | 客户端取消订阅 |
UNSUBACK | 11 | UNSUBSCRIBE 消息确认 |
PINGREQ | 12 | 心跳请求 |
PINGRESP | 13 | PINGREQ 消息确认 |
DISCONNECT | 14 | 客户端断开连接 |
Reserved | 15 | 保留 |
broker (代理): 代理是整个发布 - 订阅模型的核心,也叫 服务端
mqtt 的连接总是发生在 client 和 broker 之间,两个client 之间不会互相感知
连接过程中的消息主要包含以下内容:
在建立连接后,client 可以向 broker 订阅一个或多个话题,subscribe 消息由 client 发送给 broker
SUBSCRIBE
消息由 client 发送给 broker,包含一个 Topic 和 QoSSUBACK
消息确认 SUBSCRIBE消息是否成功抵达 broker
返回码 | 描述 |
---|---|
0x00 | 成功,QoS0 |
0X01 | 成功,QoS1 |
0X02 | 成功,QoS2 |
0X80 | 失败 |
当 client 在连接到 broker 之后就可以发送消息了,每条 publish 消息都包含一个 topic、payload
PUBLISH
消息由 client 发送给 broker,也可以由 broker 发送给 client,包含QoS、Payloads、topicname等PUBLISH
消息的接收方需要发送确认应答,不同QoS的 PUBLISH消息响应有所区别
QoS | 确认应答类型 |
---|---|
QoS 0 | 无确认应答 |
QoS 1 | PUBACK消息 |
QoS 2 | PUBREC、PUBREL、PUBCOMP消息 |
在 QoS 0 的等级的 PUBLISH 消息中不包含包唯一标识。发送者不考虑消息交付结果,接收者也不发送响应。接收者最多只能收到一次消息,也有可能一次也收不到。
在 QoS 1 等级的 PUBLISH 消息中包含包唯一标识,发送方会一直将该消息当作 “未确认” 的消息,直到收到对应的 PUBACK 确认消息。
QoS 2 是最高的服务质量,保证消息不会丢失也不会重复,缺点是会增加开销。在 QoS 2 等级的 PUBLISH 消息中包含包唯一标识,发送者会一直将该消息当作 “未确认” 的消息,直到收到对应的 PUBCOMP 确认消息。