在MQTT规范中,有连接标志,用于管理服务器和客户端上的保留和状态。
干净的会话specification建议:
3.1.2.4清除会话位置:Connect Flags字节的第1位。
此位指定会话状态的处理。客户和 服务器可以存储会话状态以启用可靠的消息传递 继续一系列网络连接。这个位用于 控制会话状态的生命周期。
如果CleanSession设置为0,则服务器必须恢复通信 与客户基于当前会议的状态(如已确定 由客户标识符)。如果没有与之关联的会话 客户端标识符服务器必须创建一个新的Session。客户和 服务器必须在客户端和服务器之后存储会话 断开[MQTT-3.1.2-4]。
断开CleanSession设置为0的Session后, 服务器必须存储与任何匹配的QoS 1和QoS 2消息 客户在断开连接时所拥有的订阅作为一部分 会话状态
因此,每当客户端在断开连接后再次连接时,代理将中继所有未确认的QoS-1和QoS-2消息。所以,经纪人有一个州。为了维护每个客户端的状态,服务器将使用一些数据库进行保留。有没有办法为这些消息状态(服务器将存储的)提供生存时间。如何告诉经纪人丢弃(即不转发)任何超过的消息;比方说5天。
基本上,我们希望使用带有QoS-1的clean session = 0;但如何用旧消息清除代理状态?即使未经确认,也不希望收到超过5天的旧邮件。
答案 0 :(得分:2)
简短回答,你不能(在规范范围内)。
根据规范,客户端的持久状态需要无限期保留。
您没有提到您正在使用的经纪人,但是mosquitto确实有以下(无标准)选项:
persistent_client_expiration 持续时间
This option allows persistent clients (those with clean session set to false) to be removed if they do not reconnect within a certain
时间范围。这是一个非标准选项。就MQTT规范而言 有关,持久的客户永远存在。
Badly designed clients may set clean session to false whilst using a randomly generated client id. This leads to persistent clients that
永远不会重新连接。此选项允许删除这些客户端。
The expiration period should be an integer followed by one of h d w m y for hour, day, week, month and year respectively. For example: persistent_client_expiration 2m persistent_client_expiration 14d persistent_client_expiration 1y As this is a non-standard option, the default if not set is to never expire persistent clients.
这意味着如果客户端脱机的时间超过指定的时间,那么将转储该客户端的所有排队消息(不会再排队)。
这可能是你能得到你想要的最接近的。
答案 1 :(得分:1)
MQTT 5.0允许设置消息过期间隔以进行发布。
https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901112
3.3.2.3.3消息有效期限
2(0x02)字节,消息到期间隔的标识符。
后跟表示消息到期的四字节整数 间隔。
如果存在,则四字节值是应用程序的生命周期 消息以秒为单位。如果消息过期间隔已经过去,并且 服务器尚未设法开始继续传送到匹配项 订户,则必须删除该消息的副本 订阅者[MQTT-3.3.2-5]。
如果不存在,则申请消息不会过期。
服务器发送给客户端的PUBLISH数据包必须包含一个 消息有效期限设置为接收值减去时间 应用消息已在服务器[MQTT-3.3.2-6]中等待。 有关存储状态的详细信息和限制,请参阅第4.1节。