Been looking into this. I suspect there is nothing we can do about this situation. If I am assessing things correctly, the MQTT.js client lib doesn't discern the difference between 2 identical topic subscriptions with different options. I may be wrong and will get back into it later.
Thinking about this, it may even be a design choice in the protocol (or at least in the MQTT.js lib implementation). I.e. the thought and design considerations may have been "why would a user want to subscribe to same topic twice"?
I regularly do this, if I want to display something on a dashboard I would have an MQTT node on that flow to pick it up. If I use it in the control logic that would be on a different tab so I would have another one there.
Yeah, I know how we as node-red user's re)use them (and it feels natural) however from a client library pov, it doesn't really make much sense since the user can distribute the packets to multiple callbacks.
Like I say, I will do more digging and see if I can come to a definite conclusion or solution. Even if that is just a note in the docs about same topic subscriptions.
I wanted to say that yes, your flow works only deletaing one MQTT in node. Now I know that this is why I didn't get any difference in my test, too. For the same reason. I had more mqtt in node having this the flag differently configured.
The point 1) (your flow) is related to the flag "Keep retain flag of original publish". it's clear and I can see different results depending on this flag setting. What I'm not able to see, is difference in the "retained message handling" option. See the image in the first message
When it talks about retained messages here it means the initial message that is sent when the node connects to the broker. With my test flow, with just one MQTT In node, if you set the option to Send Retained Messages, then if you do a Full Deploy, or Restart Flows you should see the retained message appearing in the debug node. Then for each time you click Inject you will see another message. If you set the option to Do Not Send, then when you do a full deploy, or restart flows, you should not see the initial retained message, but should still see one each time you click Inject.
Now that the V5 options exist, arguably the client library should allow for multiple connections with different options. Perhaps an issue should be raised against the library. Assuming that your initial diagnosis turns out to be correct.
And what about "only for new subscription?".
The option do not send is ok and even simple to evaluate with test. As I said, mybe the "new subscription" option is something useful for dynamic subscription that you can manage once node-red is running. otherwise, apart for "do not send" the retained message is always received
The option is a representation of the rh option in the subscribe function. That particular option sets the rh option to 1 which is defined in the oasis spec as "Send retained messages at subscribe only if the subscription does not currently exist"
Bits 4 and 5 of the Subscription Options represent the Retain Handling option. This option specifies whether retained messages are sent when the subscription is established. This does not affect the sending of retained messages at any point after the subscribe. If there are no retained messages matching the Topic Filter, all of these values act the same. The values are:
0 = Send retained messages at the time of the subscribe
1 = Send retained messages at subscribe only if the subscription does not currently exist
2 = Do not send retained messages at the time of the subscribe
It is a Protocol Error to send a Retain Handling value of 3
It was reworded in node-red to be more friendly however it would seen we missed the mark?
Still not clear to me I am afraid. How can a subscription exist prior to subscribing? Or is it referring to the multiple clients, meaning when the first client subscribes but not later ones?
Not sending retained messages for an existing subscription is useful when a reconnect is done and the Client is not certain whether the subscriptions were completed in the previous connection to the Session.
Not sending stored retained messages because of a new subscription is useful where a Client wishes to receive change notifications and does not need to know the initial state
Other than these descriptions from the official spec, I can find no better descriptions.
Fwiw: The V5 implementation in node-red was done following the oasis spec - so even though I wrote the code, it was simply parrot fashion to specification. Some parts (i.e. retained handling and subscription identifiers) were as clear as mud but the implementation was relatively straight forward - present the available subscription options to the user & pass them to the broker.
Possibly. Is the 'Send retained messages at subscribe only if the subscription does not currently exist' referring to where Clean Session is not ticked, and the client disconnects and then reconnects? So the retained message would get sent when the client initially connects, but not sent again after a disconnect/reconnect?
Apart from the "clean session" part - that is my interpretation. Retained messages are independent of the "Clean Start". If you consider there are more than just states CONNECTED and DISCONNECTED it may make it slightly clearer. For example, the RE-CONNECT operation is different to the CONNECT in that a connection was established (subscriptions were likely made and retained messages will have been sent already) however a network outage caused the connection to become INTERUPTED (not cleanly closed) and so upon re-connect, existing subscriptions are resumed. This is my understanding of 'Send retained messages at subscribe only if the subscription does not currently exist'
RE: "clean session"
In MQTT v5 the flag is slightly changed (in both name and features) it is now "clean start". From the web:
Clean Start now replaces the original Clean Session, but is no longer used to indicate whether to store session state. It is only used to indicate whether the server should attempt to restore a previous session or create a new session directly when connecting. The storage duration of the session state on the server is completely decided by Session Expiry Interval.
In particular, "clean start" is more to do with queued QoS 1 and QoS 2 messages.
OK, thanks.
Luckily I don't feel the need to make use of this subtlety, hopefully anyone who does will take the time to fully understand what it is all about.
@Lupin_III do you actually need to make use of any of these features or were you just keen to understand what it does?
No Colin, at the moment I'm ok with all this explanation, I was just keen to understand what it does. I need more the flag, and it is clear enough to me.
If someone need to understand it more and need this feature, I think it could help make some test with the dynamic subscription. For what I'm understanding, it is the only way you can subscribe to a new topic without reconnect, restart the flow. So, maybe this option can have some more sense.
Thansk to all for the support and clarification