一篇搞定MQTT

术语概述

MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT)。
MQTT是底层传输协议基础设施。

  • 客户端使用它连接服务端。
  • 它提供有序的、可靠的、双向字节流传输。

应用消息 :MQTT协议通过网络传输应用数据。应用消息通过MQTT传输时,它们联系有服务质量(QoS)和主题(Topic)。
客户端 Client(一般情况下,云下设备是客户端)
使用MQTT的程序或设备。客户端总是通过网络连接到服务端。它可以

  • 发布应用消息给其它相关的客户端。
  • 订阅以请求接受相关的应用消息。
  • 取消订阅以移除接受应用消息的请求。
  • 从服务端断开连接

服务端 Server(一般情况下,云平台是服务端)
一个程序或设备,作为发送消息的客户端和请求订阅的客户端之间的中介。服务端

  • 接受来自客户端的网络连接。
  • 接受客户端发布的应用消息。
  • 处理客户端的订阅和取消订阅请求。
  • 转发应用消息给符合条件的已订阅客户端。

服务端不是数据的终点,只是数据的中转站
订阅 Subscription
订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。
主题名 Topic Name
附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本
给每一个匹配的客户端订阅。
主题过滤器 Topic Filter
订阅中包含的一个表达式,用于表示相关的一个或多个主题。主题过滤器可以使用通配符。
会话 Session
客户端和服务端之间的状态交互。一些会话持续时长与网络连接一样,另一些可以在客户端
和服务端的多个连续网络连接间扩展。
控制报文 MQTT Control Packet
通过网络连接发送的信息数据包。MQTT规范定义了十四种不同类型的控制报文,其中一个
(PUBLISH报文)用于传输应用消息。

MQTT控制报文格式

MQTT协议通过交换预定义的MQTT控制报文来通信。MQTT控制报文由三部分组成:
在这里插入图片描述
固定报头 Fixed header
每个MQTT控制报文都包含一个固定报头

  • MQTT控制报文的类型
    位置:第1个字节,二进制位7-4。表示为4位无符号值
    在这里插入图片描述
  • 标志 Flags
    固定报头第1个字节的剩余的4位 [3-0]包含每个MQTT控制报文类型特定的标志,表格 2.2中任何标记为“保留”的标志位,都是保留给以后使用的在这里插入图片描述
  • 剩余长度 Remaining Length
    剩余长度(Remaining Length)表示当前报文剩余部分的字节数,包括可变报头和负载的数
    据。剩余长度不包括用于编码剩余长度字段本身的字节数。
    剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码。更大的值按下面
    的方式处理。低7位有效位用于编码数据,最高有效位用于指示是否有更多的字节。因此每个
    字节可以编码128个数值和一个延续位(continuation bit)。剩余长度字段最大4个字节。
    在这里插入图片描述
    可变报头 Variable header
    某些MQTT控制报文包含一个可变报头部分。它在固定报头和负载之间。可变报头的内容根据
    报文类型的不同而不同。可变报头的报文标识符(Packet Identifier)字段存在于在多个类型
    的报文里。
  • 报文标识符 Packet Identifier
    在这里插入图片描述 很多控制报文的可变报头部分包含一个两字节的报文标识符字段。这些报文是PUBLISH(QoS > 0时), PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCIBE,UNSUBACK。

SUBSCRIBE,UNSUBSCRIBE和PUBLISH(QoS大于0)控制报文必须包含一个非零的16位报文标识符(Packet Identifier)[MQTT-2.3.1-1]。客户端每次发送一个新的这些类型的报文时都必须分配一个当前未使用的报文标识符 [MQTT-2.3.1-2]。如果一个客户端要重发这个特殊的控制报文,在随后重发那个报文时,它必须使用相同的标识符。当客户端处理完这个报文对应的确认后,这个报文标识符就释放可重用。QoS 1的PUBLISH对应的是PUBACK,QoS 2的PUBLISH对应的是PUBCOMP,与SUBSCRIBE或UNSUBSCRIBE对应的分别是SUBACK或UNSUBACK [MQTT-2.3.1-3]。发送一个QoS 0的PUBLISH报文时,相同的条件也
适用于服务端 [MQTT-2.3.1-4]。QoS等于0的PUBLISH报文不能包含报文标识符 [MQTT-2.3.1-5]。
PUBACK, PUBREC, PUBREL报文必须包含与最初发送的PUBLISH报文相同的报文标识符
[MQTT-2.3.1-6]。类似地,SUBACK和UNSUBACK必须包含在对应的SUBSCRIBE和
UNSUBSCRIBE报文中使用的报文标识符 [MQTT-2.3.1-7]。需要报文标识符的控制报文在 表格 2.5 -包含报文标识符的控制报文 中列出。

包含报文标识符的控制报文 Control Packets that contain a Packet Identifier
在这里插入图片描述

有效载荷 Payload
某些MQTT控制报文在报文的最后部分包含一个有效载荷.对于PUBLISH来说有效载荷就是应用消息。
在这里插入图片描述

MQTT控制报文 MQTT Control Packets

  • CONNECT – 连接服务端
    客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CONNECT报文
    在一个网络连接上,客户端只能发送一次CONNECT报文。服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端的连接
    有效载荷包含一个或多个编码的字段。包括客户端的唯一标识符,Will主题,Will消息,用户名和密码。除了客户端标识之外,其它的字段都是可选的,基于标志位来决定可变报头中是否需要包含这些字段。
    CONNECT报文的可变报头按下列次序包含四个字段:协议名(Protocol Name),协议级别(Protocol Level),连接标志(Connect Flags)和保持连接(Keep Alive)。
    协议名 Protocol Name在这里插入图片描述
    协议级别 Protocol Level
    客户端用8位的无符号值表示协议的修订版本。对于3.1.1版协议,协议级别字段的值是4(0x04)。如果发现不支持的协议级别,服务端必须给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接 [MQTT-3.1.2-2]。
    连接标志 Connect Flags
    连接标志,一个字节,包含一些用于指定MQTT连接行为的参数。它还指出有效载荷中的字段是否存在。
    在这里插入图片描述
    清理会话 Clean Session
    在这里插入图片描述
    保留消息不是服务端会话状态的一部分,会话终止时不能删除保留消息
    当清理会话标志被设置为1时,客户端和服务端的状态删除不需要是原子操作。
    一般来说,客户端连接时总是将清理会话标志设置为0或1,并且不交替使用两种值。这个选择取决于具体的应用。清理会话标志设置为1的客户端不会收到旧的应用消息,而且在每次连接成功后都需要重新订阅任何相关的主题。清理会话标志设置为0的客户端会收到所有在它连接断开期间发布的QoS 1和QoS 2级别的消息。因此,要确保不丢失连接断开期间的消息,需要使用QoS 1或 QoS 2级别,同时将清理会话标志设置为0。
    遗嘱标志 Will Flag
    在这里插入图片描述
    服务端应该迅速发布遗嘱消息。在关机或故障的情况下,服务端可以推迟遗嘱消息的发布直
    到之后的重启。如果发生了这种情况,在服务器故障和遗嘱消息被发布之间可能会有一个延
    迟。

遗嘱QoS Will QoS
在这里插入图片描述
遗嘱保留 Will Retain
在这里插入图片描述
用户名标志 User Name Flag
位置:连接标志的第7位。
如果用户名(User Name)标志被设置为0,有效载荷中不能包含用户名字段 [MQTT-3.1.2-18]。
如果用户名(User Name)标志被设置为1,有效载荷中必须包含用户名字段 [MQTT-3.1.2-19]。
密码标志 Password Flag
位置:连接标志的第6位。
如果密码(Password)标志被设置为0,有效载荷中不能包含密码字段 [MQTT-3.1.2-20]。
如果密码(Password)标志被设置为1,有效载荷中必须包含密码字段 [MQTT-3.1.2-21]。
如果用户名标志被设置为0,密码标志也必须设置为0 [MQTT-3.1.2-22]。
保持连接 Keep Alive
在这里插入图片描述
保持连接的实际值是由应用指定的,一般是几分钟。允许的最大值是18小时12分15秒。
有效载荷 Payload
CONNECT报文的有效载荷(payload)包含一个或多个以长度为前缀的字段,可变报头中的
标志决定是否包含这些字段。如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱主
题,遗嘱消息,用户名,密码
客户端标识符 Client Identifier‘
服务端使用客户端标识符 (ClientId) 识别客户端。连接服务端的每个客户端都有唯一的客户端
标识符(ClientId)。客户端和服务端都必须使用ClientId识别两者之间的MQTT会话相关的状

客户端标识符 (ClientId) 必须存在而且必须是CONNECT报文有效载荷的第一个字段

  • CONNACK – 确认连接请求
  • PUBLISH – 发布消息
  • PUBACK –发布确认
  • PUBREC – 发布收到(QoS 2,第一步)
  • PUBREL – 发布释放(QoS 2,第二步)
  • PUBCOMP – 发布完成(QoS 2,第三步)
  • SUBSCRIBE - 订阅主题
  • SUBACK – 订阅确认
  • UNSUBSCRIBE –取消订阅
  • UNSUBACK – 取消订阅确认
  • PINGREQ – 心跳请求
  • PINGRESP – 心跳响应
  • DISCONNECT –断开连接

猜你喜欢

转载自blog.csdn.net/weixin_49456013/article/details/107607343
今日推荐