概述
交互过程是有三个部分,包括订阅方,服务器和发布方,
这种通信方式的优点就是
1、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
2、对负载内容屏蔽的消息传输;
3、使用 TCP/IP 提供网络连接;
4、有三种消息发布服务质量:
“至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
“至少一次”,确保消息到达,但消息重复可能会发生。
“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
5、小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;
6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制;
总的来说就是
多个客户端同时连接同一个服务器
不同的客户端可以订阅相同的标题,也可以订阅不同的标题
当某一设备发布某一标题时,服务器会将该标题的具体内容转发给订阅该标题的客户端
数据包结构
包含三个部分
Fixed Header固定报头, 所有控制报文都包含 |
Variable Header 可变报头, 部分控制报文包含 |
Payload 有效载荷, 部分控制报文包含 |
固定报头
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
byte 1 | MQTT控制报文的类型 | 用于指定控制报文类型的标志位 | ||||||
byte 2... | 剩余长度 |
包头高四位控制报文类型(发送时用十六进制)
名字 | 值 | 十六进制 | 报文流动方向 | 描述 |
---|---|---|---|---|
Reserved | 0 | 0 | 禁止 | 保留 |
CONNECT | 1 | 1 | 客户端到服务端 | 客户端请求连接服务端 |
CONNACK | 2 | 2 | 服务端到客户端 | 连接报文确认 |
PUBLISH | 3 | 3 | 两个方向都允许 | 发布消息 |
PUBACK | 4 | 4 | 两个方向都允许 | QoS 1 消息发布收到确认 |
PUBREC | 5 | 5 | 两个方向都允许 | 发布收到(保证交付第一步) |
PUBREL | 6 | 6 | 两个方向都允许 | 发布释放(保证交付第二步) |
PUBCOMP | 7 | 7 | 两个方向都允许 | QoS 2 消息发布完成(保证交付第三步) |
SUBSCRIBE | 8 | 8 | 客户端到服务端 | 客户端订阅请求 |
SUBACK | 9 | 9 | 服务端到客户端 | 订阅请求报文确认 |
UNSUBSCRIBE | 10 | A | 客户端到服务端 | 客户端取消订阅请求 |
UNSUBACK | 11 | B | 服务端到客户端 | 取消订阅报文确认 |
PINGREQ | 12 | C | 客户端到服务端 | 心跳请求 |
PINGRESP | 13 | D | 服务端到客户端 | 心跳响应 |
DISCONNECT | 14 | E | 两个方向都允许 | 断开连接通知 |
AUTH | 15 | F | 两个方向都允许 | 认证信息交换 |
包头低四位用于指定控制报文类型的标志位(发送时用十六进制)
MQTT控制报文 | 固定报头标志 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | 十六进制 |
---|---|---|---|---|---|---|
CONNECT | Reserved | 0 | 0 | 0 | 0 | 0 |
CONNACK | Reserved | 0 | 0 | 0 | 0 | 0 |
PUBLISH | Used in MQTT v5.0 | DUP | QOS高 | QOS低 | RETAIN | |
PUBACK | Reserved | 0 | 0 | 0 | 0 | 0 |
PUBREC | Reserved | 0 | 0 | 0 | 0 | 0 |
PUBREL | Reserved | 0 | 0 | 1 | 0 | 2 |
PUBCOMP | Reserved | 0 | 0 | 0 | 0 | 0 |
SUBSCRIBE | Reserved | 0 | 0 | 1 | 0 | 2 |
SUBACK | Reserved | 0 | 0 | 0 | 0 | 0 |
UNSUBSCRIBE | Reserved | 0 | 0 | 1 | 0 | 2 |
UNSUBACK | Reserved | 0 | 0 | 0 | 0 | 0 |
PINGREQ | Reserved | 0 | 0 | 0 | 0 | 0 |
PINGRESP | Reserved | 0 | 0 | 0 | 0 | 0 |
DISCONNECT | Reserved | 0 | 0 | 0 | 0 | 0 |
AUTH | Reserved | 0 | 0 | 0 | 0 | 0 |
DUP = PUBLISH报文的重复分发标志
重复分发标志
如果DUP标志被设置为0, 表示这是客户端或服务端第一次请求发送这个PUBLISH报文. 如果DUP标志被设置为1, 表示这可能是一个早前报文请求的重发.
客户端或服务端请求重发一个PUBLISH报文时, 必须将DUP标志设置为1
对于QoS为0的消息, DUP标志 必须设置为0
QoS = PUBLISH报文的服务质量等级
QoS值 | Bit 2 | Bit 1 | 说明 |
---|---|---|---|
0 | 0 | 0 | 最多分发一次 |
1 | 0 | 1 | 至少分发一次 |
2 | 1 | 0 | 仅分发一次 |
- | 1 | 1 | 保留 – 不能使用 |
可变报头
报文标识符
部分类型MQTT控制报文的可变报头部分包含了2个字节的报文标识符字段. 这些MQTT控制报文类型为:PUBLISH报文(当QoS>0时), PUBACK, PUBREC, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK.
需要报文标识符的MQTT控制报文如下表所示.
MQTT控制报文 | 报文标识符字段 |
---|---|
CONNECT | 不需要 |
CONNACK | 不需要 |
PUBLISH | 需要(如果QoS > 0) |
PUBACK | 需要 |
PUBREC | 需要 |
PUBREL | 需要 |
PUBCOMP | 需要 |
SUBSCRIBE | 需要 |
SUBACK | 需要 |
UNSUBSCRIBE | 需要 |
UNSUBACK | 需要 |
PINGREQ | 不需要 |
PINGRESP | 不需要 |
DISCONNECT | 不需要 |
AUTH | 不需要 |
客户端每次发送一个新的SUBSCRIBE, UNSUBSCRIBE或者PUBLISH(当QoS>0时)MQTT控制报文时都必须分配一个当前未使用的非零报文标识符。
服务端每次发送一个新的PUBLISH(当QoS>0)MQTT控制报文时都必须分配一个当前未使用的非零报文标识符 。
当客户端处理完这个报文对应的确认后, 这个报文标识符就释放可重用. QoS 1的PUBLISH对应的是PUBACK, QoS 2的PUBLISH对应的是包含原因码128以上的PUBCOMP或PUBREC, 与SUBSCRIBE或UNSUBSCRIBE对应的分别是SUBACK或UNSUBACK。
PUBLISH, SUBSCRIBE和UNSUBSCRIBE的报文标识符, 在一次会话中对于客户端和服务端来说分属于不同的组. 某个报文标识符在某一时刻不能被多个命令所使用。
PUBACK, PUBREC和PUBREL报文必须包含与最初发送的PUBLISH报文相同的报文标识符 . 类似地, SUBACK和UNSUBACK 必须 包含在对应的SUBSCRIBE和UNSUBSCRIBE报文中使用的报文标识符。
客户端和服务端彼此独立地分配报文标识符. 因此, 客户端服务端组合使用相同的报文标识符可以实现并发的消息交换。
属性
CONNECT, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBACK, DISCONNECT 和 AUTH 报文可变报头的最后一部分是一组属性. CONNECT 报文的遗嘱(Will)属性字段中也包含了一组可选的属性.
属性长度被编码为变长字节整数. 属性长度不包含用于编码属性长度自身的字节数, 但包含所有属性的长度. 如果没有任何属性, 必须由属性长度为零的字段来指示。
标识符 | 属性名(用途) | 数据类型 | 报文/遗嘱属性 | |
---|---|---|---|---|
DEC | HEX | |||
1 | 0x01 | 载荷格式说明 | 字节 | PUBLISH, Will Properties |
2 | 0x02 | 消息过期时间 | 四字节整数 | PUBLISH, Will Properties |
3 | 0x03 | 内容类型 | UTF-8编码字符串 | PUBLISH, Will Properties |
8 | 0x08 | 响应主题 | UTF-8编码字符串 | PUBLISH, Will Properties |
9 | 0x09 | 相关数据 | 二进制数据 | PUBLISH, Will Properties |
11 | 0x0B | 定义标识符 | 变长字节整数 | PUBLISH, SUBSCRIBE |
17 | 0x11 | 会话过期间隔 | 四字节整数 | CONNECT, CONNACK, DISCONNECT |
18 | 0x12 | 分配客户标识符 | UTF-8编码字符串 | CONNACK |
19 | 0x13 | 服务端保活时间 | 双字节整数 | CONNACK |
21 | 0x15 | 认证方法 | UTF-8编码字符串 | CONNECT, CONNACK, AUTH |
22 | 0x16 | 认证数据 | 二进制数据 | CONNECT, CONNACK, AUTH |
23 | 0x17 | 请求问题信息 | 字节 | CONNECT |
24 | 0x18 | 遗嘱延时间隔 | 四字节整数 | Will Properties |
25 | 0x19 | 请求响应信息 | 字节 | CONNECT |
26 | 0x1A | 请求信息 | UTF-8编码字符串 | CONNACK |
28 | 0x1C | 服务端参考 | UTF-8编码字符串 | CONNACK, DISCONNECT |
31 | 0x1F | 原因字符串 | UTF-8编码字符串 | CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT, AUTH |
33 | 0x21 | 接收最大数量 | 双字节整数 | CONNECT, CONNACK |
34 | 0x22 | 主题别名最大长度 | 双字节整数 | CONNECT, CONNACK |
35 | 0x23 | 主题别名 | 双字节整数 | PUBLISH |
36 | 0x24 | 最大QoS | 字节 | CONNACK |
38 | 0x26 | 用户属性 | UTF-8字符串对 | CONNECT, CONNACK, PUBLISH, Will Properties, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, DISCONNECT, AUTH |
39 | 0x27 | 最大报文长度 | 四字节整数 | CONNECT, CONNACK |
40 | 0x28 | 通配符订阅可用性 | 字节 | CONNACK |
41 | 0x29 | 订阅标识符可用性 | 字节 | CONNACK |
42 | 0x2A | 共享订阅可用性 | 字节 | CONNACK |