关于MQTT连接的属性

  • 连接相关的属性.

这些属性是MQTT的连接报文中连接标志字, 包含一些用于指定 MQTT 连接行为的参数.

1.清理会话(Clean Session)

客户端和服务端可以保存会话状态,以支持跨网络连接的可靠消息传输. 这个标志位用于控制会话状态的生存时间.

值为0. 客户端和服务器端基于会话状态(用客户端标识符识别)恢复与客户端的通信.服务器端没有该标识符, 则创建新的会话. 当连接断开后, 客户端和服务端必须保存会话信息. 同时, 服务器端必须保存客户端订阅过的QoS1和QoS2级别的消息为会话的一部分.

值为1. 客户端和服务端必须丢弃之前的任何会话并开始一个新的会话.会话仅持续和网络连接同样长的时间. 与这个会话关联的状态数据不能被任何之后的会话重用.

客户端的会话状态包括:
 已经发送给服务端, 但是还没有完成确认的 QoS 1 和 QoS 2 级别的消息.
 已从服务端接收, 但是还没有完成确认的 QoS 2 级别的消息.
服务端的会话状态包括:
 会话是否存在, 即使会话状态的其它部分都是空.
 客户端的订阅信息.
 已经发送给客户端, 但是还没有完成确认的 QoS 1 和 QoS 2 级别的消息.
 即将传输给客户端的 QoS 1 和 QoS 2 级别的消息.
 已从客户端接收, 但是还没有完成确认的 QoS 2 级别的消息.
 可选, 准备发送给客户端的 QoS 0 级别的消息.

保留消息不是服务端会话状态的一部分, 会话终止时不能删除保留消息.

关键点:

1. 为了确保在发生故障时状态的一致性, 客户端应该使用会话状态标志 1 重复请求连接, 直到连接成功.

2.一般来说, 客户端连接时总是将清理会话标志设置为 0 或 1,并且不交替使用两种值。 这个选择取决于具体的应用.

清理会话标志设置为 1 的客户端不会收到旧的应用消息, 而且在每次连接成功后都需要重新订阅任何相关的主题.

清理会话标志设置为 0 的客户端会收到所有在它连接断开期间发布的 QoS 1 和 QoS 2 级别的消息.因此, 要确保不丢失连接断开期间的消息, 需要使用 QoS 1 或QoS 2 级别,同时将清理会话标志设置为 0.

清理会话标志 0 的客户端连接时, 服务端在连接断开后会保留它的 MQTT 会话状态. 如果打
算在之后的某个时间点重连到这个服务端, 客户端连接应该只使用清理会话标志 0.

当客户端决定之后不再使用这个会话时,应该将清理会话标志设置为 1 最后再连接一次,然后断开连接.(释放服务器资源).

清理会话规定了会话的时效性. 标志为0, 可以保障MQTT协议消息可靠递出, 即便有延时; 标志为1, 可以节约服务器资源.

2.遗嘱标志(Will Flag)

遗嘱标志(Will Flag) 被设置为 1,表示如果连接请求被接受了, 遗嘱消息(Will Message) 必须被存储在服务端并且与这个网络连接关联。当网络连接关闭时,服务端必须发布这个遗嘱消息, 除非服务端收到DISCONNECT 报文时删除了这个遗嘱消息

遗嘱消息发布的条件, 包括但不限于:
 服务端检测到了一个 I/O 错误或者网络故障.
 客户端在保持连接(Keep Alive)的时间内未能通讯.
 客户端没有先发送 DISCONNECT 报文直接关闭了网络连接.
 由于协议错误服务端关闭了网络连接.

如果遗嘱标志被设置为 1,连接标志中的 Will QoS 和 Will Retain 字段会被服务端用到, 同时有效载荷中必须包含 Will Topic 和 Will Message 字段 .

一旦被发布或者服务端收到了客户端发送的 DISCONNECT 报文, 遗嘱消息就必须从存储的会话状态中移除 .

如果遗嘱标志被设置为 0, 连接标志中的 Will QoS 和 Will Retain 字段必须设置为 0, 并且有效载荷中不能包含 Will Topic 和 Will Message 字段.

如果遗嘱标志被设置为 0,网络连接断开时, 不能发送遗嘱消息.

服务端应该迅速发布遗嘱消息。在关机或故障的情况下, 服务端可以推迟遗嘱消息的发布直到之后的重启.如果发生了这种情况, 在服务器故障和遗嘱消息被发布之间可能会有一个延迟.

遗嘱标志确定了传输链路发生故障时MQTT协议的后手保障方案, 通过遗嘱消息告诉订阅者某个客户端发生故障.

3.遗嘱消息质量(Will QoS)

遗嘱消息质量用于指定发布遗嘱消息时使用的服务质量等级. 只有使用了遗嘱标志, 改项才能设置非0参数.

0. 最多发送一次.  (发送一次完事)

1. 最少发送一次.  (可能发送多次,必须接到应答)

2. 可靠发送一次.  (只发送一次, 并保证送达)

遗嘱消息质量规定了遗嘱消息发布的可靠性等级.

4.遗嘱保留(Will Retain)

只有使用了遗嘱标志, 改项才能设置非0参数.

遗嘱保留为 0, 服务端必须将遗嘱消息当作非保留消息发布 .

遗嘱保留为 1, 服务端必须将遗嘱消息当作保留消息发布 .

遗嘱保留规定了遗嘱消息发布后的留存问题.

5.用户名标志(User Name Flag)

设置为 0, 有效载荷中不能包含用户名字段.
设置为 1, 有效载荷中必须包含用户名字段.

用户名标志表示MQTT协议允许匿名登录.具体和服务端的实现相关.

6. 密码标志(Password Flag)

设置为 0, 有效载荷中不能包含密码字段.
设置为 1, 有效载荷中必须包含密码字段.
如果用户名标志被设置为 0, 密码标志也必须设置为 0.

密码标志表示匿名登录不能有密码, 非匿名登录可以只用用户名,也可以用户名+密码.

  • 发布相关的属性.

1.重发标志(DUP)

如果 DUP 标志被设置为 0, 表示这是客户端或服务端第一次请求发送这个 PUBLISH 报文。 如果 DUP 标志被设置为 1,表示这可能是一个早前报文请求的重发。

客户端或服务端请求重发一个 PUBLISH 报文时, 必须将 DUP 标志设置为 1.

对于 QoS0 的消息, DUP 标志必须设置为 0.

服务端发送 PUBLISH 报文给订阅者时, 收到(入站) 的 PUBLISH 报文的 DUP 标志的值不会被传播。 发送(出站) 的 PUBLISH 报文与收到(入站) 的 PUBLISH 报文中的 DUP 标志是独立设置的, 它的值必须单独的根据发送(出站) 的 PUBLISH 报文是否是一个重发来确定 .

关键点:

1.接收者收到一个 DUP 标志为 1 的控制报文时, 不能假设它看到了一个这个报文之前的一个副本.

2.需要特别指出的是, DUP 标志关注的是控制报文本身, 与它包含的应用消息无关.

当使用 QoS 1时, 客户端可能会收到一个 DUP 标志为 0 的 PUBLISH 报文, 这个报文包含一个它之前收到过的应用消息的副本, 但是用的是不同的报文标识符。

重发标志和使用MQTT的用户无关, 和MQTT服务端和客户端实现相关.

2.服务质量等级(QoS)

这个字段表示应用消息分发的服务质量等级保证。

0. 最多发送一次.  (发送一次完事)

1. 最少发送一次.  (可能发送多次,必须接到应答)

2. 可靠发送一次.  (只发送一次, 并保证送达)

3.保留标志(Retain)

如果客户端发给服务端的 PUBLISH 报文的保留(RETAIN) 标志被设置为 1, 服务端必须存储这个应用消息和它的服务质量等级(QoS) ,以便它可以被分发给未来的主题名匹配的订阅者 .

一个新的订阅建立时,对每个匹配的主题名,如果存在最近保留的消息, 它必须被发送给这个订阅者 .

如果服务端收到一条保留(RETAIN) 标志为 1 的 QoS 0 消息, 它必须丢弃之前为那个主题保留的任何消息. 它应该将这个新的 QoS 0 消息当作那个主题的新保留消息,但是任何时候都可以选择丢弃它. 如果这种情况发生了, 那个主题将没有保留消息 .

服务端发送 PUBLISH 报文给客户端时,如果消息是作为客户端一个新订阅的结果发送, 它必须将报文的保留标志设为 1.

当一个 PUBLISH 报文发送给客户端是因为匹配一个已建立的订阅时,服务端必须将保留标志设为 0, 不管它收到的这个消息中保留标志的值是多少.

保留标志为 1 且有效载荷为零字节的 PUBLISH 报文会被服务端当作正常消息处理,它会被发送给订阅主题匹配的客户端。此外,同一个主题下任何现存的保留消息必须被移除,因此这个主题之后的任何订阅者都不会收到一个保留消息 . 服务端不能存储零字节的保留消息.

如果客户端发给服务端的 PUBLISH 报文的保留标志位 0, 服务端不能存储这个消息也不能移除或替换任何现存的保留消息.

保留消息标志标示着这条消息比较重要, 新的订阅者需要收到. 新的保留消息会覆盖旧的保留消息, 空的保留消息会清空以往的保留消息.

  • 订阅主题相关的属性

1. Requested QoS

这个属性是订阅报文有效载荷的一部分, 用于表示订阅的服务质量要求.

以上参考了《MQTT-3.1.1-CN》. 如发现错误, 敬请留言!!

上一篇:使用 API 网关构建微服务-2


下一篇:Linux gadget驱动分析3------复合设备驱动