Reputation: 153
I want to use the mqtt package for nodejs. Everywhere I look, I find code samples like this one (from official doc on github) :
const mqtt = require('mqtt')
const client = mqtt.connect('mqtt://test.mosquitto.org')
client.on('connect', function () {
client.subscribe('presence', function (err) {
if (!err) {
client.publish('presence', 'Hello mqtt')
}
})
})
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString())
client.end()
})
My problem is that the connection: mqtt.connect() is before the callback: client.on('connect', ...). I think it is the wrong order. From what I understand, we send a CONNECT packet, then declare what to do when receiving a CONNACK packet.
This is different from the python package where you instanciate a client, then you declare "on connect" and other callbacks, and only then you use a method client.connect(). From what I understand, you declare what to do when receiving a CONNACK packet, then send a CONNECT packet.
Is there a way to guarantee the correct order (like in the python package) ?
Edit : The main concern is that if the CONNACK message comes back very quickly, and the code to declare the "on connect" callback is inside some complicated conditions, the "on connect" callback could not trigger (because the connection is already done) and there will be no client.subscribe, so our client will not be subscribed to the intended topic.
I guess it is theorically possible but practically impossible ? But what if the code is a bit bigger ? I actually played with this a while ago and had a code where sometimes the subscription was made, and other times the subscription was missed, depending on the speed of the CONNACK response I guess. (The code just waited a certain amount of time, maybe 0.1seconds, before declaring the "on connect" callback)
Upvotes: 0
Views: 495
Reputation: 463
You kind of guessed it right here
I guess it is theorically possible but practically impossible
Just that it's theoretically impossible too in Javascript.
See, the connect
method connects to the MQTT server (test.mosquitto.org
in our case).
And its a IO call which will be executed asynchronously as Non-Blocking IO call
So what happens is this,
connect
callback)connect
eventSo the JS event loop (read more here) will never process the connection established event before registering the connect
callback, thus ensuring the code always works.
Upvotes: 1
Reputation: 110
I don't know what is write on python pack, but if we look on official Mqtt docks correct order is:
client.on('message', console.log)
) to handle incoming messagesEdit 1 client.on('message', console.log) or client.on('connect', console.log) will work immediately when events was published by EventEmitter
Edit 2 i will try to describe the 3 points above more verbosely using your code example
// try connect to Mqtt server (point 1)
const client = mqtt.connect('mqtt://test.mosquitto.org')
// when connection is done
client.on('connect', function () {
// try to subscribe to some topic (point 2)
client.subscribe('presence', function (err) {
if (!err) {
client.publish('presence', 'Hello mqtt')
}
})
})
// when we got some message from mqtt we call a callback function (point 3)
client.on('message', function (topic, message) {
console.log(message.toString())
// and close the client
client.end()
})
Edit 3 Declaration of "on connect" callback, will be faster than connection. This mechanic is called micro and macrotasks. Try this example in console:
setTimeout(() => console.log('connection'), 0)
console.log('add callback')
console.log('add callback')
console.log('add callback')
console.log('add callback')
console.log('add callback')
Upvotes: 2