2

In the MQTT specification there are connect flags which governs the retention and state on server and client.

The clean session specification suggests:

3.1.2.4 Clean Session Position: bit 1 of the Connect Flags byte.

This bit specifies the handling of the Session state. The Client and Server can store Session state to enable reliable messaging to continue across a sequence of Network Connections. This bit is used to control the lifetime of the Session state.

If CleanSession is set to 0, the Server MUST resume communications with the Client based on state from the current Session (as identified by the Client identifier). If there is no Session associated with the Client identifier the Server MUST create a new Session. The Client and Server MUST store the Session after the Client and Server are disconnected [MQTT-3.1.2-4].

After the disconnection of a Session that had CleanSession set to 0, the Server MUST store further QoS 1 and QoS 2 messages that match any subscriptions that the client had at the time of disconnection as part of the Session state

So, whenever client is connecting again after a disconnect the broker would relay all QoS-1 and QoS-2 messages which are not acknowledged. So, broker has a state. And to maintain the state for every client, the server would use some database for retention. Is there a way to give Time to Live for these messages state (which the server would store). How to tell broker to drop (i.e, not to relay) any messages which is older than; let say 5 days.

Basically, we want to use clean session = 0 with QoS-1; but how to clear broker state with old messages? Don't want to receive older messages than 5 days, even when unacknowledged.

enator
  • 2,431
  • 2
  • 28
  • 46

2 Answers2

4

MQTT 5.0 allows setting a Message Expiry Interval for publish.

https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901112

3.3.2.3.3 Message Expiry Interval

2 (0x02) Byte, Identifier of the Message Expiry Interval.

Followed by the Four Byte Integer representing the Message Expiry Interval.

If present, the Four Byte value is the lifetime of the Application Message in seconds. If the Message Expiry Interval has passed and the Server has not managed to start onward delivery to a matching subscriber, then it MUST delete the copy of the message for that subscriber [MQTT-3.3.2-5].

If absent, the Application Message does not expire.

The PUBLISH packet sent to a Client by the Server MUST contain a Message Expiry Interval set to the received value minus the time that the Application Message has been waiting in the Server [MQTT-3.3.2-6]. Refer to section 4.1 for details and limitations of stored state.

enator
  • 2,431
  • 2
  • 28
  • 46
Andrew
  • 4,696
  • 1
  • 19
  • 17
  • any idea if one is supposed to set the expiry as epoch(kind of a full date+time) or number of seconds it should be kept FROM the moment message is arrived ? – Harsh Gundecha Aug 27 '21 at 10:30
  • https://www.hivemq.com/blog/mqtt5-essentials-part4-session-and-message-expiry/#:~:text=Message%20Expiry%20Interval%20in%20seconds - expiry in seconds from "now" – simonalexander2005 Aug 07 '23 at 08:04
3

Short answer, you can't (while staying within v3.0 spec).

According to the spec persistent state for clients needs to be preserved indefinitely.

You didn't mention which broker you are using but mosquitto does have the following (none standard) option:

persistent_client_expiration duration

This option allows persistent clients (those with clean session set to false) to be removed if they do not reconnect within a certain

time frame. This is a non-standard option. As far as the MQTT spec is concerned, persistent clients persist forever.

Badly designed clients may set clean session to false whilst using a randomly generated client id. This leads to persistent clients that

will never reconnect. This option allows these clients to be removed.

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.

This means that if a client is offline for longer than the specified time then all queued messages for that client will be dumped (and no more will be queued).

This is probably the closest you can get to what you want.

hardillb
  • 54,545
  • 11
  • 67
  • 105
  • Thanks for the explanation. I am using EMQ - http://emqtt.io/ - will have to find out if something similar is supported there. – enator Jan 03 '18 at 06:35
  • However, my client_id is always constant. so it wont serve the purpose. – enator Jan 03 '18 at 06:42