eclipse / paho.mqtt.java

Eclipse Paho Java MQTT client library. Paho is an Eclipse IoT project.
https://eclipse.org/paho
Other
2.08k stars 879 forks source link

Message Order Not Preserved #966

Open Donadominic opened 1 year ago

Donadominic commented 1 year ago

While using NanoMQ when the client is disconnected and connected back again the order in which the messages are published is not preserved. It is reading data in some random order. But when the client is connected the messages are received in proper order. How to receive messages in proper order?

I was sending a sequence of messages when the client was disconnected. And when the client is connected back again I am expecting the messages to be received in the proper order they are send.

Publisher Code public class Publisher { public static void main(String[] args) {

try {
    //publishing a message
    MqttClient client=new MqttClient("tcp://192.168.2.8:1885",MqttClient.generateClientId(),new MemoryPersistence());
    MqttConnectOptions options = new MqttConnectOptions();
    options.setCleanSession(false);
    options.setUserName("user1");
    options.setPassword("password".toCharArray());
    client.connect(options);

    MqttMessage message=new MqttMessage();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

    for(int i=1;i<=20;i++) {
        Date date = new Date();
        String str=simpleDateFormat.format(date)+"    message "+i;
        message.setPayload(str.getBytes());
        message.setQos(2);
        message.setRetained(true);
        client.publish("iot_data_1",message);
    }

    client.disconnect();

} catch(MqttException me) {
    System.out.println(me);
}

} }

Consumer Code public class Subscriber3 { public static void main(String[]args) throws MqttException { MqttClient client =new MqttClient("tcp://192.168.2.8:1885","subscriber004",new MemoryPersistence()); MqttConnectOptions options=new MqttConnectOptions(); options.setCleanSession(false); options.setUserName("user009"); options.setPassword("password008".toCharArray()); client.connect(options);

client.setCallback(new MqttCallback() {
    @Override
    public void connectionLost(Throwable cause) {
        System.out.println("Connection lost");
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        System.out.println(new String(message.getPayload()));
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        System.out.println("Delivery Complete");
    }
});

client.subscribe("iot_data_1");
//client.disconnect();

} }

But messages are received in some random order. All the messages are received. But I need them in the order they are published.

NanoMQ latest version Java Client in Windows and NanoMq on ubuntu centos in docker container Java- Eclipse Paho Publishing a sequence of messages when the client is disconnected and when client is connected back need persisted messages in order

I need messages in the order in which they are published not in some random order.

oreillymj commented 1 year ago

The MQTT spec does not preserve message ordering. You need to add a serial number to your body if you want to preserve ordering in the client side logic.

https://stackoverflow.com/questions/30955110/is-message-order-preserved-in-mqtt-messages/30959058#30959058

Actually, on further reading, 3.1.1 should be ordered but perhaps Paho does not implement this.

https://groups.google.com/g/mqtt/c/UfcO0HtLq9s

Anyway, I would add a serial number to the payload to identify out of order messages on the client and logic to buffer messages if ordering is important to your business logic.