Message persistence in MQTT clients

Publication messages are made persistent if they are sent with a quality of service of "at least once", or "exactly once". You can implement your own persistence mechanism on the client, or use the default persistence mechanism that is provided with the client. Persistence works in both directions, for publications sent to or from the client.
In MQTT, message persistence has two aspects; how the message is transferred, and whether it is queued in IBM® MessageSight and IBM WebSphere® MQ as a persistent message.
  1. The MQTT client couples message persistence with quality of service. Depending on what quality of service you choose for a message, the message is made persistent. Message persistence is necessary to implement the required quality of service.
    • If you specify "at most once", QoS=0, the client discards the message as soon as it is published. If there is any failure in the upstream processing of the message, the message is not sent again. Even if the client remains active the message is not sent again. The behavior of QoS=0 messages is the same as IBM WebSphere MQ fast nonpersistent messages.
    • If a message is published by a client with QoS of 1 or 2, it is made persistent. The message is stored locally, and only discarded from the client when it is no longer needed to guarantee "at least once", QoS=1, or "exactly once", QoS=2, delivery.
  2. If a message is marked as QoS 1 or 2, it is queued in IBM MessageSight and IBM WebSphere MQ as a persistent message. If it is marked as QoS=0, then it is queued in IBM MessageSight and IBM WebSphere MQ as a nonpersistent message. In IBM WebSphere MQ nonpersistent messages are transferred between queue managers "exactly once", unless the message channel has the NPMSPEED attribute set to FAST.

A persistent publication is stored on the client until it is received by a client application. For QoS=2, the publication is discarded from the client when the application callback returns control. For QoS=1 the application might receive the publication again, if a failure occurs. For QoS=0, the callback receives the publication no more than once. It might not receive the publication if there is a failure, or if the client is disconnected at the time of publication.

When you subscribe to a topic, you can reduce the QoS with which the subscriber receives messages to match its persistence capabilities. Publications that are created at a higher QoS are sent with the highest QoS that the subscriber requested.

Storing messages

The implementation of data storage on small devices varies a great deal. The model of temporarily saving persistent messages in storage that is managed by the MQTT client might be too slow, or demand too much storage. In mobile devices, the mobile operating system might provide a storage service that is ideal for MQTT messages.

To provide flexibility in meeting the constraints of small devices, the MQTT client has two persistence interfaces. The interfaces define the operations that are involved in storing persistent messages. The interfaces are described in the API documentation for the MQTT client for Java. For links to client API documentation for the MQTT client libraries, see MQTT client programming reference. You can implement the interfaces to suit a device. The MQTT client that runs on Java SE has a default implementation of the interfaces that store persistent messages in the file system. It uses the java.io package. The client also has a default implementation for Java ME, MqttDefaultMIDPPersistence.

Persistence classes

MqttClientPersistence
Pass an instance of your implementation of MqttClientPersistence to the MQTT client as a parameter of the MqttClient constructor. If you omit the MqttClientPersistence parameter from the MqttClient constructor, the MQTT client stores persistent messages using the class MqttDefaultFilePersistence or MqttDefaultMIDPPersistence.
MqttPersistable
MqttClientPersistence gets and puts MqttPersistable objects using a storage key. You must provide an implementation of MqttPersistable as well as the implementation of MqttClientPersistence if you are not using the MqttDefaultFilePersistence or MqttDefaultMIDPPersistence.
MqttDefaultFilePersistence

The MQTT client provides the MqttDefaultFilePersistence class. If you instantiate MqttDefaultFilePersistence in your client application, you can provide the directory to store persistent messages as a parameter of the MqttDefaultFilePersistence constructor.

Alternatively, the MQTT client can instantiate MqttDefaultFilePersistence and place files in a default directory. The name of the directory is client identifier-tcp hostname portnumber. "\", "\\", "/", ":" and " " are removed from the directory name string.

The path to the directory is the value of the system property rcp.data. If rcp.data is not set, the path is the value of the system property usr.data.

rcp.data is a property associated with installation of an OSGi or Eclipse Rich Client Platform (RCP).

usr.data is the directory in which the Java command that started the application was launched.

MqttDefaultMIDPPersistence
MqttDefaultMIDPPersistence has a default constructor and no parameters. It uses the javax.microedition.rms.RecordStore package to store messages.