moquette icon indicating copy to clipboard operation
moquette copied to clipboard

retain flag does not work qith qos=0 in version 0.17

Open AndroidDesigner opened this issue 1 year ago • 9 comments

Hello. I have cloned the moquette version 0.17 inside of my java project, but retain flag does not work with qos = 0, while I remember it was working in older versions of the moquette. note: The moquette version 0.17 works with qos > 0, but unfortunately my own IoT Things need to qos = 0.

I have tested it by using mosquitto_pub and mosquitto_sub as the below:

  • First publish a sample topic: mosquitto_pub -h host.com -p moqttPort -u username1 -P password1 -i clientID1 -t topic1 -m message1 -r -q 0

  • Then subscribe to get last published (retained) message of the above topic: mosquitto_sub -h host.com -p mqttPort -u username2 -P password2 -i clientID2 -t topic1

but nothing is received by the subscriber.

AndroidDesigner avatar Jun 23 '24 16:06 AndroidDesigner

I'll check this, but from MQTT specification http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html :

If the Server receives a QoS 0 message with the RETAIN flag set to 1 it MUST discard any message previously retained for that topic. It SHOULD store the new QoS 0 message as the new retained message for that topic, but MAY choose to discard it at any time - if this happens there will be no retained message for that topic [MQTT-3.3.1-7].

So the server MUSTN'T store the retain in session state if the QoS is 0.

However I'll check this. Thanks for reporting!

andsel avatar Jun 24 '24 12:06 andsel

Your welcome dear @andsel Did you implement MQTT 5.0 in the code? You wrote in #808 :

Retain As Published

The Retain As Published option has two possible values, 0 and 1.

    1 means the server should preserve the Retain flag unchanged when forwarding application messages to subscribers
    0 means that the Retain flag must be cleared.
    Also this setting is used in bridging situations.

It seems you have used this logic in the moquette version 0.17.

AndroidDesigner avatar Jun 25 '24 06:06 AndroidDesigner

Did you implement MQTT 5.0 in the code? I'm implementing it, but for v0.18-SNAPSHOT

It seems you have used this logic in the moquette version 0.17.

How it's possible if the Retain As Published option only exists in MQTT5 subscribe and that code is part of 0.18?

Retain As Published relates to the fact that the retain flag of a publish message should be forwarded as it's received from the publisher (used in proxy use cases) or must be cleared. But this is unspecified in MQTT3 (if I'm not wrong).

While the problem you are reporting relates to the fact that a publish with QoS0 and retained = true it's not effectively retained, as I can understand from your description.

andsel avatar Jun 25 '24 07:06 andsel

How it's possible if the Retain As Published option only exists in MQTT5 subscribe and that code is part of 0.18?

Retain As Published relates to the fact that the retain flag of a publish message should be forwarded as it's received from the publisher (used in proxy use cases) or must be cleared. But this is unspecified in MQTT3 (if I'm not wrong).

I know what you mean, but I thought maybe you did it (MQTT 5.0 in version 0.17) wrong. So, you must check your implementation to check why retain=true does not work with QoS=0 in version 0.17. You can check it simply using the below:

#First publish a sample topic:
mosquitto_pub -h host.com -p moqttPort -u username1 -P password1 -i clientID1 -t topic1 -m message1 -r -q 0

#Then subscribe to get last published (retained) message of the above topic:
mosquitto_sub -h host.com -p mqttPort -u username2 -P password2 -i clientID2 -t topic1

While the problem you are reporting relates to the fact that a publish with QoS0 and retained = true it's not effectively retained, as I can understand from your description.

Exactly! That's what I mean

AndroidDesigner avatar Jun 25 '24 07:06 AndroidDesigner

MQTT 5.0 in version 0.17

Just a note, Moquette v0.17 doesn't implement MQTT5

andsel avatar Jun 25 '24 07:06 andsel

I think your logic for Qos=0 is wrong! Because there is a lot use cases where we need to retain messages for IoT things with QoS=0. I have read the PostOffice class and I think you should call the manageRetain() method in the receivedPublishQos1() method too.

AndroidDesigner avatar Nov 17 '24 15:11 AndroidDesigner

I think your logic for Qos=0 is wrong! Because there is a lot use cases where we need to retain messages for IoT things with QoS=0.

I think that's outside of specification [MQTT-3.3.1-7] where the sentence:

It SHOULD store the new QoS 0 message as the new retained message for that topic, 
but MAY choose to discard it at any time - if this happens there will be no retained message for that topic.

Give the ability to the broker implementation what to do on retained QoS0 publishes. Please could you explain better where is the error in the logic for QoS0? In worst case the client can always use QoS1 messages.

andsel avatar Nov 17 '24 16:11 andsel

Give the ability to the broker implementation what to do on retained QoS0 publishes. Please could you explain better where is the error in the logic for QoS0? In worst case the client can always use QoS1 messages.

There is a lot of MQTT clients for IoT devices (written to C, C++), but they have problems with QoS=1,2. Also I think it would be a good option if the broker can supply different situations like this. You can simply consider to retain messages for QoS=0 by a config parameter.

AndroidDesigner avatar Nov 18 '24 07:11 AndroidDesigner

You can simply consider to retain messages for QoS=0 by a config parameter.

Yep I think we can do that. Please close this issue an open one describing such feature, citing the use case.

andsel avatar Nov 18 '24 08:11 andsel