基于MQTT 3.1版本,标准MQTT发布遗嘱消息的几种情况。
如果想设置遗嘱消息,那么客户端请求和代理服务器链接之前,必须把遗嘱消息提前填写好,在请求连接时,把遗嘱消息发给代理服务器。
MQTT遗嘱消息,什么时候订阅者会收到代理服务器发布的遗嘱消息?以下四种情况:
服务端发生了I/O 错误或者网络失败;
客户端在定义的心跳时期失联;
客户端在发送下线包之前关闭网络连接;
服务端在收到下线包之前关闭网络连接。
遗嘱标志 Will Flag
位置: 连接标志的第2位。
遗嘱标志( 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, 网络连接断开时, 不能发送遗嘱消息。
服务端应该迅速发布遗嘱消息。 在关机或故障的情况下, 服务端可以推迟遗嘱消息的发布直到之后的重启。 如果发生了这种情况, 在服务器故障和遗嘱消息被发布之间可能会有一个延迟。
遗嘱QoS Will QoS
位置: 连接标志的第4和第3位。
这两位用于指定发布遗嘱消息时使用的服务质量等级。
如果遗嘱标志被设置为0, 遗嘱QoS也必须设置为0(0x00)。
如果遗嘱标志被设置为1, 遗嘱QoS的值可以等于0(0x00), 1(0x01), 2(0x02)。 它的值不能是除此之外其他值。
遗嘱保留 Will Retain
位置: 连接标志的第5位。
如果遗嘱消息被发布时需要保留, 需要指定这一位的值。
如果遗嘱标志被设置为0, 遗嘱保留( Will Retain) 标志也必须设置为 0 。
如果遗嘱标志被设置为1:
如果遗嘱保留被设置为0, 服务端必须将遗嘱消息当作非保留消息发布。
如果遗嘱保留被设置为1, 服务端必须将遗嘱消息当作保留消息发布。
遗嘱主题 Will Topic
如果遗嘱标志被设置为1, 有效载荷的下一个字段是遗嘱主题( Will Topic) 。 遗嘱主题必须是1.5.3节定义的UTF-8编码字符串。
遗嘱消息 Will Message
如果遗嘱标志被设置为1, 有效载荷的下一个字段是遗嘱消息。 遗嘱消息定义了将被发布到遗嘱主题的应用消息, 这个字段由一个两字节的长度和遗嘱消息的有效载荷组成, 表示为零字节或多个字节序列。 长度给出了跟在后面的数据的字节数, 不包含长度字段本身占用的两个字节。
遗嘱消息被发布到遗嘱主题时, 它的有效载荷只包含这个字段的数据部分, 不包含开头的两个长度字节。
服务器端:
服务端实现可以监视客户端的行为, 检测潜在的安全风险。 例如:
重复的连接请求
重复的身份验证请求
连接的异常终止
主题扫描( 请求发送或订阅大量主题)
发送无法送达的消息( 没有订阅者的主题)
客户端连接但是不发送数据
发现违反安全规则的行为, 服务端实现可以断开客户端连接(MQTT服务器,可以添加其他对mqtt客户端限制的条件)。
服务端实现检测不受欢迎的行为, 可以基于IP地址或客户端标识符实现一个动态黑名单列表。
服务部署可以使用网络层次控制( 如果可用) 实现基于IP地址或其它信息的速率限制或黑名单。
遗嘱消息需要注意的点:
遗嘱Qos Will Qos
如果遗嘱标志设置为0,遗嘱的Qos也必须设置为0;
如果遗嘱标志设置为1,遗嘱的Qos可以等于0,1,2;
遗嘱保留Will Retain
如果遗嘱标志设置为0,遗嘱保留(Will Retain)标志位也必须设置为0;
如果遗嘱标志设置为1,分为两种:
如果遗嘱保留(Will Retain)设置为0,服务器必须将遗嘱消息当做非保留消息发布;
如果遗嘱保留(Will Retain)设置为1,服务器必须将遗嘱消息当做保留消息发布;
注意:
正常状态下发布者断开MQTT连接,正常关闭MQTT链路,设置的遗嘱消息是不会被代理服务器发布出去的。
软件设计时,需要检查参数个数,每个参数都需要判断,willretained,willqos,willtopic,willmessage,如果有一个参数设置超出范围,或者设置错误其他的参数都应该清空。不要产生参数“重影”,即有的参数设置错误,有的参数设置正确,应当防止这种情况的出现。