2

在 MQTT 规范中,有一些连接标志来管理服务器和客户端上的保留和状态。

干净的会话规范建议:

3.1.2.4 清除会话位置:连接标志字节的第 1 位。

该位指定会话状态的处理。客户端和服务器可以存储会话状态,以使可靠的消息传递在一系列网络连接中继续。该位用于控制 Session 状态的生命周期。

如果 CleanSession 设置为 0,则服务器必须根据当前会话的状态(由客户端标识符标识)恢复与客户端的通信。如果没有与客户端标识符关联的会话,服务器必须创建一个新会话。客户端和服务器断开后,客户端和服务器必须存储会话 [MQTT-3.1.2-4]。

在将 CleanSession 设置为 0 的 Session 断开连接后,服务器必须存储更多的 QoS 1 和 QoS 2 消息,这些消息与客户端在断开连接时拥有的任何订阅相匹配,作为 Session 状态的一部分

因此,每当客户端在断开连接后再次连接时,代理都会中继所有未确认的 QoS-1 和 QoS-2 消息。所以,经纪人有一个状态。为了维护每个客户端的状态,服务器将使用一些数据库进行保留。有没有办法为这些消息状态(服务器将存储)提供生存时间。如何告诉代理丢弃(即不中继)任何早于的消息;让说5天。

基本上,我们希望使用干净的会话 = 0 和 QoS-1;但是如何用旧消息清除代理状态?不希望收到超过 5 天的旧消息,即使未确认。

4

2 回答 2

4

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 节。

于 2019-06-27T23:53:44.050 回答
3

简短的回答,你不能(同时保持在 v3.0 规范内)。

根据规范,客户端的持久状态需要无限期地保留。

您没有提及您使用的是哪个经纪人,但 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.

这意味着如果客户端离线时间超过指定时间,则该客户端的所有排队消息都将被转储(不再排队)。

这可能是您可以得到的最接近您想要的东西。

于 2018-01-02T19:05:28.627 回答