遗嘱音讯是 MQTT 为那些可能呈现 意外断线 的设施提供的将 遗嘱 优雅地发送给第三方的能力。意外断线包含但不限于:
- 因网络故障或网络稳定,设施在放弃连贯周期内未能通信,连贯被服务端敞开
- 设施意外掉电
- 设施尝试进行不被容许的操作而被服务端敞开连贯,例如订阅本身权限以外的主题等
遗嘱音讯能够看作是一个简化版的 PUBLISH 音讯,他也蕴含 Topic, Payload, QoS 等字段。遗嘱音讯会在设施与服务端连贯时,通过 CONNECT 报文指定,而后在设施意外断线时由服务端将该遗嘱音讯公布到连贯时指定的遗嘱主题(Will Topic)上。这也意味着服务端必须在回复 CONNACK 之前实现遗嘱音讯的存储,以确保之后任一时刻发生意外断线的状况,服务端都能保障遗嘱音讯被公布。
以下为遗嘱音讯在 MQTT 5.0 和 MQTT 3.1 & 3.1.1 的差别:
MQTT 5.0 | MQTT 3.1 & 3.1.1 | |
---|---|---|
Will Retain | Yes | Yes |
Will QoS | Yes | Yes |
Will Flag | Yes | Yes |
Will Properties | Yes | No |
Will Topic | Yes | Yes |
Will Payload | Yes | Yes |
Will Retain、Will QoS、Will Topic 和 Will Payload 的用途与一般 PUBLISH 报文基本一致,这里不再赘述。
惟一值得一提的是 Will Retain 的应用场景,它是保留音讯与遗嘱音讯的联合。如果订阅该遗嘱主题(Will Topic)的客户端不能保障遗嘱音讯公布时在线,那么倡议为遗嘱音讯设置 Will Retain,防止订阅端错过遗嘱音讯。
Will Flag 通常是 MQTT 协定实现方关怀的字段,它用于标识 CONNECT 报文中是否会蕴含 Will Properties、Will Topic 等字段。
最初一个是 MQTT 5.0 新增的 Will Properties 字段,属性自身也是 MQTT 5.0 的一个新个性,不同类型的报文有着不同的属性,例如 CONNECT 报文有会话过期间隔(Session Expiry Interval)、最大报文长度(Maximum Packet Size)等属性,SUBSCRIBE 报文则有订阅标识符(Subscription Identifier)等属性。
Will Properties 中的音讯过期间隔(Message Expiry Interval)等属性与 PUBLISH 报文中的用法基本一致,只有一个遗嘱提早距离(Will Delay Interval)是遗嘱音讯特有的属性。
遗嘱提早距离顾名思义,就是在连贯断开后提早一段时间才公布遗嘱音讯。它的一个重要用处就是防止在设施因网络稳定短暂断开连接,但可能疾速复原连贯持续提供服务时收回遗嘱音讯,并对遗嘱音讯订阅方造成困扰。
须要留神的是,具体提早多久公布遗嘱音讯,除了遗嘱提早距离,还受限于会话过期间隔,取决于两者谁先产生。所以当咱们将会话过期间隔设置为 0 时,即会话在网络连接敞开时过期,那么不论遗嘱提早距离的值是多少,遗嘱音讯都会在网络连接断开时立刻公布。
演示遗嘱音讯的应用
接下来咱们应用 EMQ X 和 MQTT X 来演示一下遗嘱音讯的理论应用。
为了实现 MQTT 连贯被异样断开的成果,咱们须要调整一下 EMQ X 的默认 ACL 规定与相干配置项:
首先在 etc/acl.conf
中增加以下 ACL 规定,示意回绝本机客户端连贯公布 test 主题。留神须要加在所有默认 ACL 规定之前,以确保这条规定能胜利失效:
{deny, {ipaddr, "127.0.0.1"}, publish, ["test"]}.
而后批改 etc/emqx.conf
中 zone.internal.acl_deny_action
配置项,将其设置为 ACL 查看回绝时断开客户端连贯:
zone.internal.acl_deny_action = disconnect
实现以上批改后,咱们启动 EMQ X。
接下来,咱们在 MQTT X 中新建一个名为 demo 的连贯,Host 批改为 localhost,在 Advanced 局部抉择 MQTT Version 为 5.0,并且将 Session Expiry Interval 设置为 10,确保会话不会在遗嘱音讯公布前过期。
而后在 Lass Will and Testament 局部将 Last-Will Topic 设置为 offline,Last-Will Payload 设置为 I'm offline
,Will Delay Interval (s) 设置为 5。
实现以上设置后,咱们点击右上角的 Connect 按钮以建设连贯。
而后咱们再创立一个名为 subscriber 的客户端连贯,并订阅 offline 主题。
接下来咱们回到 demo 连贯中,公布一个 Topic 为 test 的任意内容音讯,这时连贯会被断开,急躁期待五秒钟,咱们将看到 subscriber 连贯收到了一条内容为 I‘m offline
的遗嘱音讯。
进阶应用场景
这里介绍一下如何将 Retained 音讯与 Will 音讯联合起来进行应用。
- 客户端 A 遗嘱音讯内容设定为
offline
,该遗嘱主题与一个一般发送状态的主题设定成同一个A/status
。 - 当客户端 A 连贯时,向主题
A/status
发送内容为online
的 Retained 音讯,其它客户端订阅主题A/status
的时候,将获取到 Retained 音讯为online
。 - 当客户端 A 异样断开时,零碎主动向主题
A/status
发送内容为offline
的音讯,其它订阅了此主题的客户端会马上收到offline
音讯;如果遗嘱音讯设置了 Will Retain,那么此时如果有新的订阅A/status
主题的客户端上线,也将获取到内容为offline
的遗嘱音讯。