MQTT协议详解
1 术语定义
客户端 Client:
· 发布应用消息给其它相关的客户端。
· 订阅以请求接受相关的应用消息。
· 取消订阅以移除接受应用消息的请求。
· 从服务端断开连接
服务端 Server:
· 接受来自客户端的网络连接。
· 接受客户端发布的应用消息。
· 处理客户端的订阅和取消订阅请求。
· 转发应用消息给符合条件的已订阅客户端
订阅 Subscription:
订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。
主题名 Topic Name:
附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本给每一个匹配的客户端订阅。
主题过滤器 Topic Filter:
订阅中包含的一个表达式,用于表示相关的一个或多个主题。可以使用通配符。
会话 Session:
客户端和服务端之间的状态交互。一些会话持续时长与网络连接一样,另一些可以在客户端和服务端的多个连续网络连接间扩展。
2 MQTT报文结构
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
byte 1 | 报文类型(14种) | DUP | Qos(3种) | RETAIN | ||||
byte 2 | 剩余长度=可变报头长度+有效载荷长度 | |||||||
byte 3 | 可变报头(此处举例子5个字节,实际根据报文类型决定) | |||||||
byte 4 byte 5 | ||||||||
byte 6 | ||||||||
byte 7 | 有效载荷 |
2.1 报文类型
协议类型 | 值 | 描述 |
Reserved | 0 | 保留 |
CONNECT | 1 | 客户端请求连接服务端 |
CONNACK | 2 | 连接报文确认 |
PUBLISH | 3 | 发布消息 |
PUBACK | 4 | 发布消息确认 |
PUBREC | 5 | 发布收到(保证交付第一步) |
PUBREL | 6 | 发布释放(保证交付第二步) |
PUBCOMP | 7 | QoS 2消息发布完成(保证交互第三步) |
SUBSCRIBE | 8 | 客户端订阅请求 |
SUBACK | 9 | 订阅请求报文确认 |
UNSUBSCRIBE | 10 | 取消订阅报文请求 |
UNSUBACK | 11 | 取消订阅报文确认 |
PINGREQ | 12 | 心跳请求 |
PINGRESP | 13 | 心跳确认 |
DISCONNECT | 14 | 断开连接 |
Reserved | 15 | 保留 |
2.2 DUP描述
DUP Value | 描述 |
0 | 消息第一次传输 |
1 | 消息已经传输过一次,现在是再次传输。但是不能作为Qos=1重复的检测依据 |
2.3 Qos Level描述
Qos Level | bit 2 | bit 1 | 描述 |
0 | 0 | 0 | 至多一次传输,不能保证消息到达服务器,客户端发完就释放 |
1 | 0 | 1 | 服务器接收到消息会被确认,通过传输一个PUBACK信息。如果有一个可以辨认的传输失败,无论是通讯连接还是发送设备,还是过了一段时间确认信息没有收到,发送方都会将消息头的DUP位置1,然后再次发送消息。消息最少一次到达服务器。 |
2 | 1 | 0 | 准确传输一次。在QoS level 1上附加的协议流保证了重复的消息不会传送到接收的应用 |
2.4 消息保留描述(RETAIN)
RETAIN | 描述 |
0 | 仅仅为当前订阅者推送此消息。 |
1 | 表示发送的消息需要一直持久保存(不受服务器重启影响),不但要发送给当前的订阅者,并且以后新来的订阅了此Topic name的订阅者会马上得到推送。 |
2.5 剩余长度
剩余长度为变长字节编码方案。每个字节的最高位为1则代表后面还跟有一个长度字节,为0则表示长度字节到此结束。长度字节标识的长度为可变报头和有效载荷的长度。剩余长度字节最多为4个。可表示的字节范围如下:
Digits | From | To |
1 | 0 (0x00) | 127 (0x7F) |
2 | 128 (0x80, 0x01) | 16 383 (0xFF, 0x7F) |
3 | 16 384 (0x80, 0x80, 0x01) | 2 097 151 (0xFF, 0xFF, 0x7F) |
4 | 2 097 152 (0x80, 0x80, 0x80, 0x01) | 268 435 455 (0xFF, 0xFF, 0xFF, 0x7F) |
2.6 可变报头(CONNECT报文)
可变报头是随着报文协议不同而变化的。这里详细着重介绍CONNECT报文,CONNECT报文的可变报头按下列次序包含四个字段:协议名(Protocol Name),协议级别(Protocol Level),连接标志(Connect Flags)和保持连接(Keep Alive)。
Protocol Name:协议名是表示协议名 MQTT 的UTF-8编码的字符串,如果定义有误的话,服务端会拒绝客户端的连接请求。
Protocol Level:客户端用8位的无符号值表示协议的修订版本。对于3.1.1版协议,协议级别字段的值是4(0x04)。如果发现不支持的协议级别,服务端必须给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接
Clean session :
0 | server需要存储client的订阅。包括存储Qos 1和2的订阅主题(当client重连时能将消息发送);当连接丢失的时候 服务器必须维护正在发送的消息的状态直到客户端重新连接到服务器。 |
1 | server MUST忽略之前维护关于client的信息,并且将该connection当成clean的。server MUST 忽略任何client断开的状态。 |
Will Flag:
在自己异常断开的情况下,一个由客户端预先定义好的主题和对应消息,附加在CONNECT的可变头部中,在客户端连接出现异常的情况下,由服务器主动发布此消息。
Will Qos:
两位表示,和PUBLISH消息固定头部的QoS level含义一样。
若标识了Will Flag值为1,那么Will QoS就会生效,否则会被忽略掉。
Will RETAIN:
如果设置Will Flag,Will Retain标志就是有效的,否则它将被忽略。
当客户端意外断开服务器发布其Will Message之后,服务器是否应该继续保存。
User name 和password Flag:
用于授权,两者要么为0要么为1,否则都是无效。都为0,表示客户端可自由连接/订阅,都为1,表示连接/订阅需要授权。
2.7 有效载荷
有效载荷有可变报头部分决定,例如CONNECT报文中可变报头ConnectFlags中定义了Username 和password Flag,则此部分会附加用户名和密码字符串
3 报文交互介绍