2 个版本
0.1.1 | 2018年12月9日 |
---|---|
0.1.0 | 2018年12月8日 |
#756 在 文本处理
43 每月下载量
64KB
1.5K SLoC
RustMqtt
纯 Rust 的 Mqtt 编码和解码器。
说明
mqtt
数据包的字序为Big-Endian
,意味着所有字节将按MSB ->
LSB
排列。- 字符串/文本值是
UTF-8
,格式为2-byte
+n-bytes
,其中前2-byte
是字符串长度,另外n-bytes
是实际文本数据。文本字段的最大长度为65535
字节。
控制包
所有的 MQtt
控制包由三部分组成。
固定头部
,存在于所有 MQTT 控制包中。可变头部
,存在于某些 MQTT 控制包中。负载
,存在于某些 MQTT 控制包中。
1. 固定头部
- 固定头部中的第一个字节包含各种设置以及此数据包的类型。
7th 6th 5th 4th
,这4 位
是数据包类型。3rd 2nd 1st 0th
,这4 位
是数据包特定
。主要用于publish
数据包类型。
- 从第二个字节开始是整个数据包的实际剩余长度,包括可变头部和负载(如果有)。
- 剩余长度使用变长编码方案进行编码,该方案使用一个字节表示值直到 127。较大的值处理方式如下。每个字节的最低有效位 7 位编码数据,最高有效位用于指示表示中还有后续的字节。因此,每个字节编码 128 个值和“延续位”。剩余长度字段中字节数的最大值为四个。
-
do encodedByte = X MOD 128 X = X DIV 128 // if there are more data to encode, set the top bit of this byte if ( X > 0 ) encodedByte = encodedByte OR 128 endif 'output' encodedByte while ( X > 0 )
2. 可变头部
- 某些类型的 MQTT 控制包包含一个可变头部组件。它位于固定头部和负载之间。可变头部的内容取决于数据包类型。可变头部的数据包标识符字段在几种数据包类型中是通用的。
数据包标识符
- 非零
2 字节
更长。 - 这些控制包包括 PUBLISH(QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。
- 非零
3. 负载数据
- 一些 MQTT 控制包包含一个作为包最后部分的负载数据。
Control Packet Payload
CONNECT Required
CONNACK None
PUBLISH Optional
PUBACK None
PUBREC None
PUBREL None
PUBCOMP None
SUBSCRIBE Required
SUBACK Required
UNSUBSCRIBE Required
UNSUBACK None
PINGREQ None
PINGRESP None
DISCONNECT None
MQTT 控制包
-
CONNECT
client
请求连接到server
。- 客户端到服务器建立网络连接后,客户端发送的第一个包必须是这个。
client
在每个网络连接中只能发送 1 个 CONNECT 包。固定头
7th 6th 5th 4th
->0 0 0 1
3rd 2nd 1st 0th
->0 0 0 0
剩余长度
可变头
协议名称
- 这是一个 UTF-8 编码的字符串值。
- 可能值:用于 3.1.1 的
MQTT
协议版本
1 字节
包含 mqtt 的版本。- 对于最新版本,它是
4
。
连接标志
1 字节
包含所有所需的连接标志。7th bit
->username
6th bit
->password
5th bit
->will retain
4th 3rd bits
->Will QoS
2nd bit
->Will Flag
1st bit
->Clean Session
0th bit
->Reserved
心跳
2 字节
包含关于心跳的信息。- 这是以
seconds
为单位的值。
负载数据
Client ID
->UTF-8
编码的唯一字符串。Will Topic
- 如果
will flag
是1
- UTF-8 编码的字符串。
- 如果
Will Message
- 如果
will flag
是1
- UTF-8 编码的字符串。
- 如果
Username
- 如果
username flag
是1
- UTF-8 编码的字符串。
- 如果
Password
- 如果
password flag
是1
- UTF-8 编码的字符串。
- 如果
-
CONNACK
- 确认连接请求
固定头
- 是
0 0 1 0 0 0 0 0
。
- 是
剩余长度
- 是
0 0 0 0 0 0 1 0
。
- 是
可变头
1st byte
是0 0 0 0 0 0 SP
,其中SP
是Session Present
。第2个字节
是返回码
。-
0 0x00 Connection Accepted 1 0x01 Connection Refused, The Server does not support the level of the MQTT protocol requested by the Client 2 0x02 Connection Refused, identifier rejected The Client identifier is correct UTF-8 but not allowed by the Server 3 0x03 Connection Refused, Server unavailable 4 0x04 Connection Refused, bad user name or password 5 0x05 Connection Refused, not authorized 6 - 255 Reserved.
-
-
PUBLISH
- 数据包用于当
客户端
想向服务器
发送数据,或者服务器
想向客户端
发送数据时。 固定头1个字节
第7位 6位 5位 4位
->0 0 1 1
,这是消息类型。第3位
->DUP 标志
,- 如果 DUP = 0,则这是客户端或服务器第一次尝试发送消息。如果 DUP = 1,则这可能是一次重新尝试发送消息。
- 对于 QoS = 0,DUP 将始终为 0。
第2位 1位
->QoS 级别
- 0,1,2 的值。
第1位
-> '保留标志'- 当此值为 1 时,我们将存储此消息,并在订阅完成后立即向所有新订阅者发布。
剩余长度第2..字节
可变头
主题名称
-> 我们试图发布的消息的某种键,UTF-8
。PacketID
->u16
数据包 id 以标识消息。
负载数据
- 有效载荷中数据的类型是应用程序特定的。
- 如果
Qos = 0
对于PUBLISH
数据包,则接收器不会向发送器发送任何响应。
- 数据包用于当
-
PUBACK
- 当
Qos = 1
在PUBLISH
数据包中时,接收器会向发送器发送此数据包。 固定头
0 1 0 0 0 0 0 0
剩余长度
0 0 0 0 0 0 1 0
可变头
PacketId
-> 2 字节
- 无有效载荷。
- 当
-
PUBREC
- 当
Qos=2
在PUBLISH
中时,接收器会向发送器发送PUBREC
数据包。 固定头
0 1 0 1 0 0 0 0
剩余长度
0 0 0 0 0 0 1 0
可变头
PacketID
-> 这是我们在发布数据包时接收到的数据包 id。
- 无有效载荷。
- 当
-
PUBREL
- 这是对
PUBREC
数据包的响应。发送者收到接收器发送的PUBREC
后从发送者发送到接收者。 固定头
0 1 1 0 0 0 1 0
剩余长度
0 0 0 0 0 0 1 0
可变头
PacketId
-> 收到PUBREC
时接收到的相同数据包 id。
- 无有效载荷。
- 这是对
-
PUBCOMP
- 这是对
PUBREL
数据包的响应。接收器在从发送器收到PUBREL
后向发送器发送。 固定头
0 1 1 1 0 0 1 0
剩余长度
0 0 0 0 0 0 1 0
可变头
PacketId
-> 收到PUBREL
时接收到的相同数据包 id。
- 无有效载荷。
- 这是对
-
SUBSCRIBE
- 此数据包从
客户端
发送到服务器
以创建订阅
。 - 每个订阅注册客户端对一个或多个
主题
的兴趣。 - 当服务器想要向客户端发送
PUBLISH
数据包时使用。 Subscribe
数据包还描述了服务器可以发送到客户端的MAX QoS
。固定头
1 0 0 0 0 0 1 0
剩余长度第2..字节
可变头
PacketID
-> 唯一的 u16 id,用于标识数据包。
负载数据
- 主题过滤器列表加上
QoS
。其中主题过滤器必须是 UTF-8 编码的字符串。
- 主题过滤器列表加上
- 此数据包从
-
SUBACK
- 服务器从服务器发送到客户端以确认特定主题过滤器上的客户端订阅。
- 这包含返回码列表,指定了每个订阅中授予的最大 QoS。
固定头
1 0 0 1 0 0 0 0
剩余长度
- 可变头和有效载荷的长度。
可变头
- 数据包 ID
负载数据
- 负载包含返回码列表。每个返回码对应于被确认的SUBSCRIBE数据包中的主题过滤器。
Allowed return codes: 0x00 - Success - Maximum QoS 0 0x01 - Success - Maximum QoS 1 0x02 - Success - Maximum QoS 2 0x80 - Failure ```
-
取消订阅
- 从
客户端
发送到服务器
,以取消对一个或多个主题的兴趣。 固定头
1 0 1 0 0 0 1 0
剩余长度
可变头
- 数据包 ID
负载数据
- 客户端希望取消订阅的主题过滤器列表。
- 主题必须是UTF-8编码的字符串。
- 从
-
取消订阅确认
- 取消订阅确认数据包由
服务器
发送到客户端
,以确认收到取消订阅数据包。 固定头
1 0 1 1 0 0 0 0
剩余长度
可变头
- 从取消订阅请求接收到的数据包ID。
- 没有负载。
- 取消订阅确认数据包由
-
PING请求
- PING请求数据包由客户端发送到服务器。
- 在没有从客户端发送到服务器的其他控制数据包的情况下,通知服务器客户端是活跃的。
- 请求服务器响应以确认其活跃状态。
- 通过网络活动来指示网络连接是活跃的。
固定头
1 1 0 0 0 0 0 0
- 剩余长度为0。
- 没有负载或可变头。
-
PING响应
- 服务器在接收到PING请求数据包后,发送PING响应数据包到客户端。这表明服务器是活跃的。
固定头
1 1 0 1 0 0 0 0
- 剩余长度为0。
- 没有负载或可变头。
-
断开连接
- 断开连接数据包是客户端发送到服务器的最后一个控制数据包。这表示客户端正在干净地断开连接。
固定头
1 1 1 0 0 0 0 0
- 剩余长度为0。
- 没有负载或可变头。
- 发送此数据包后,客户端必须关闭网络连接,并不再发送任何控制数据包。
- 如果客户端未能这样做,服务器应关闭客户端连接,并拒绝接收来自客户端的新数据包。
依赖关系
~120KB