Best way to check the connected state of an MQTT node before publishing?

#1

We would like to log data locally if (a) the MQTT node isn't connected to the broker or (b) the message fails to publish. What's the best way to check the connected state before publishing, and if connected, to confirm that a message has been published?

Thanks!

#2

https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels/

#3

You can also subscribe to the topic you are publishing and check if you receive it with a MQTT in node.

#4

thanks for the reply, so a separate MQTT subscription that listens for a PUBACK is required?

#5

No, QOS levels handle the PUBACK. Normally you just set QOS to 1 or 2 and trust MQTT to do it's job. My suggestion was just if you wanted to check that the publish was OK. If you want to monitor MQTT traffic I suggest using software like MQTT Explorer or MQTT-Spy.

#6

You can use a Status node to tell you the current state of the connection.

#7

Note - the status only reflects what MQTT sees. Depending on where the network connection breaks it may need the MQTT keepalive to fail in order to detect the breakage - which by default we set to 60 seconds. Any messages sent in that period will be handled by MQTT a) if using QoS2 to send them and clean-session is set to false.and b) you don't lose power at the client end (as we do not persist them to "disk"). Once the disconnect has been detected then any other messages to be sent will be dropped - so an alternative queue (possibly triggered by the status/status node) can be created.

A simple example would be like this

[{"id":"f9ec7a29.852b18","type":"inject","z":"82738787.0e0338","name":"","topic":"test","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":600,"wires":[["8e6485b.fc3ce78"]]},{"id":"d25c0e58.e75d7","type":"mqtt out","z":"82738787.0e0338","name":"","topic":"","qos":"2","retain":"","broker":"5085b198.064c4","x":630,"y":600,"wires":[]},{"id":"ccb84c90.3f15e","type":"debug","z":"82738787.0e0338","name":"","active":false,"console":"false","complete":"false","x":650,"y":660,"wires":[]},{"id":"8e6485b.fc3ce78","type":"function","z":"82738787.0e0338","name":"Status gated queue","func":"\nvar MAX_DEPTH = 10;\n\n// if queue doesn't exist, create it\ncontext.queue = context.queue || [];\ncontext.pass = context.pass || false;\n\n// Use MQTT connected status to gate flow\nif (msg.hasOwnProperty(\"status\")) {\n    if (msg.status.text.indexOf(\".connected\") !== -1) { \n        setTimeout(function() { \n            while (context.queue.length > 0) {\n                var m = context.queue.shift();\n                node.send(m); \n            }\n            context.pass = true; \n            node.status({});\n        },5);\n    }\n    else { context.pass = false; }\n}\nelse {\n    if (context.pass) { return msg; }\n    else { \n        context.queue.push(msg); \n        if (context.queue.length > MAX_DEPTH) { context.queue.shift(); }\n        node.status({text:context.queue.length});\n    }\n}\nreturn null;","outputs":1,"noerr":0,"x":430,"y":600,"wires":[["ccb84c90.3f15e","d25c0e58.e75d7"]]},{"id":"147525f9.9ff5ba","type":"status","z":"82738787.0e0338","name":"","scope":["d25c0e58.e75d7"],"x":220,"y":660,"wires":[["8e6485b.fc3ce78"]]},{"id":"5085b198.064c4","type":"mqtt-broker","z":"","name":"","broker":"myremotebroker","port":"1883","clientid":"test","usetls":false,"compatmode":true,"keepalive":"20","cleansession":false,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

This has a maximum queue depth of 10 (just for demo) and again only persists in memory.

#8

very helpful, thank you!