MQTT-协议原理
- ■ MQTT-协议原理
- ■ MQTT-服务器 称为"消息代理"(Broker)
- ■ MQTT协议中的订阅、主题、会话
- ■ 一、订阅(Subscription)
- ■ 二、会话(Session)
- ■ 三、主题名(Topic Name)
- ■ 四、主题筛选器(Topic Filter)
- ■ 五、负载(Payload)
- ■ MQTT协议数据包结构
- ■ (1)固定报头(Fixed header)
- ■ 1.1 MQTT控制报文的类型
- ■ 1.2 报文类型标志位
- ■ 1.3 剩余长度
- ■ (2)可变报头(Variable header)
- ■ (3)消息体(Payload)也称 有效载荷
- ■ MQTT 控制报文
- ■ CONNECT – 连接服务端
- ■ CONNACK – 确认连接请求
- ■ PUBLISH – 发布消息
- ■ PUBACK –发布确认
- ■ SUBSCRIBE - 订阅主题
- ■ 通配符
- ■ 多层通配符 ‘#’ U+0023
- ■ 单层通配符 ‘+’ U+002B
- ■ $开头的主题
■ MQTT-协议原理
MQTT协议中有三种身份: 发布者(Publish)、 代理(Broker)(服务器)、 订阅者(Subscribe)。
MQTT传输的消息分为: 主题(Topic) 负载(payload)
■ MQTT-服务器 称为"消息代理"(Broker)
MQTT服务器以称为"消息代理"(Broker),可以是一个应用程序或一台设备。
它是位于消息发布者和订阅者之间,它可以:
(1)接受来自客户的网络连接;
(2)接受客户发布的应用信息;
(3)处理来自客户端的订阅和退订请求;
(4)向订阅的客户转发应用程序消息。
■ MQTT协议中的订阅、主题、会话
■ 一、订阅(Subscription)
订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。
■ 二、会话(Session)
每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。
■ 三、主题名(Topic Name)
连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。
■ 四、主题筛选器(Topic Filter)
一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。
■ 五、负载(Payload)
消息订阅者所具体接收的内容。
■ MQTT协议数据包结构
在MQTT协议中,一个MQTT数据包由:固定报头(Fixed header)、可变报头(Variable header)、消息体(payload)三部分构成。MQTT数据包结构如下:
(1)固定报头(Fixed header)。存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识。
(2)可变报头(Variable header)。存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。
(3)消息体(Payload)。也是效载荷 存在于部分MQTT数据包中,表示客户端收到的具体内容。
■ (1)固定报头(Fixed header)
固定包头包含
控制报文类型
控制报文标志位
剩余长度
剩余长度是可变的 1-4 个字节
■ 1.1 MQTT控制报文的类型
■ 1.2 报文类型标志位
[3-0]包含每个 MQTT 控制报文类型特定的标志
DUP1 =控制报文的重复分发标志
QoS2 = PUBLISH 报文的服务质量等级
RETAIN3 = PUBLISH 报文的保留标志
■ 1.3 剩余长度
位置: 从第 2 个字节开始。
剩余长度(Remaining Length) 表示当前报文剩余部分的字节数, 包括可变报头和负载的数据。
剩余长度 不包括用于编码剩余长度字段本身的字节数。
剩余长度字段 使用一个变长度编码方案:
对小于 128 的值它使用单字节编码。
更大的值按下面的方式处理。低 7 位有效位用于编码数据,最高有效位用于指示是否有更多的字节。
因此每个字节可以编码 128 个数值和一个延续位(continuation bit) 。
剩余长度字段最大 4 个字节。
例如:剩余长度字节长度是64 剩余长度填充的值就是一个字节表示64。
答 :对小于 128 的值它使用单字节编码。
例如:剩余长度是321 剩余长度填充的值 如下:
答 :大于 128 低 7 位有效位用于编码数据
计算原理
321-128 = 193 //193又大于128 在减去
193-128 = 65
第一个字节: 193
第二个字节: 2 // 321 / 128 = 2 相当于上面减去两次128
假如 第二个字节又大于128 在进行上面计算原理。
■ (2)可变报头(Variable header)
可变报头的内容根据报文类型的不同而不同。
可变报头的报文标识符(Packet Identifier) 字段存在于在多个类型的报文里。
控制报文的可变报头部分包含两字节的报文标识符字段。
■ (3)消息体(Payload)也称 有效载荷
■ MQTT 控制报文
■ CONNECT – 连接服务端
(1)固定报头
(1)可变报头-协议名
协议名是表示协议名 MQTT 的 UTF-8 编码的字符串。
(3)协议级别
客户端用 8 位的无符号值表示协议的修订版本 对于 3.1.1 版协议,协议级别字段的值是 4(0x04)。
(4)连接标志
清理会话 Clean Session | 客户端和服务端可以保存会话状态,以支持跨网络连接的可靠消息传输。 这个标志位用于控制会话状态的生存时间。 |
遗嘱标志 Will Flag | 遗嘱标志(Will Flag) 被设置为 1,表示如果连接请求被接受了, 遗嘱(Will Message) 消息必须被存储在服务端并且与这个网络连接关联。 |
遗嘱 QoS | 这两位用于指定发布遗嘱消息时使用的服务质量等级。 |
遗嘱保留 | |
用户名标志 | |
密码标志 Password Flag | |
保持连接 | 保持连接(Keep Alive) 是一个以秒为单位的时间间隔,表示为一个 16 位的字,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻, 两者之间允许空闲的最大时间间隔。 客户端负责保证控制报文发送的时间间隔不超过保持连接的值。 |
■ CONNACK – 确认连接请求
CONNACK 报文没有有效载荷。
■ PUBLISH – 发布消息
DUP 标志被设置为 0, 表示这是客户端或服务端第一次请求发送这个 PUBLISH 报文。
如果 DUP 标志被设置为 1,表示这可能是一个早前报文请求的重发。
示例中的主题名为 “a/b”, 长度等于 3, 报文标识符为 “10
■ PUBACK –发布确认
PUBACK 报文没有有效载荷。
■ SUBSCRIBE - 订阅主题
■ 通配符
■ 多层通配符 ‘#’ U+0023
(‘#’ U+0023) 是用于匹配主题中任意层级的通配符。
多层通配符表示它的父级和任意数量的子层级。
多层通配符必须位于它自己的层级或者跟在主题层级分隔符后面。
例如, 如果客户端订阅主题 “sport/tennis/player1/#”, 它会收到使用下列主题名发布的消息:
“sport/tennis/player1”
“sport/tennis/player1/ranking”
“sport/tennis/player1/score/wimbledon”
“sport/#”也匹配单独的 “sport” , 因为 # 包括它的父级。
“#”是有效的, 会收到所有的应用消息。
“sport/tennis/#”也是有效的。
“sport/tennis#”是无效的。
“sport/tennis/#/ranking”是无效的。
■ 单层通配符 ‘+’ U+002B
加号 (‘+’ U+002B) 是只能用于单个主题层级匹配的通配符。
非规范评注
例如, “sport/tennis/+”
匹配
“sport/tennis/player1”
“sport/tennis/player2” ,
但是不匹配
“sport/tennis/player1/ranking” 。同时, 由于单层通配符只能匹配一个层级, “sport/+” 不匹配
“sport” 但是却匹配 “sport/”。
非规范评注
“+” 是有效的。
“+/tennis/#” 是有效的。
“sport+” 是无效的。
“sport/+/player1” 也是有效的。
“/finance” 匹配 “+/+” 和 “/+” ,但是不匹配 “+”。