MQTT keeps running inside a function node

Hi all, I was trying to use the mqtt nodejs package inside a function node, so I implemented the "require" function as suggested in this comment in github:

So my code is this one:

require = global.get('require');
var mqtt = require('mqtt');

client  = mqtt.connect('mqtt://test.mosquitto.org');

client.on('connect', function () {
    client.subscribe('test/test/test', function (err) {
        if (!err) client.publish('test/test/test', 'Hello mqtt');
    });
});

context.global.publish=function(msg){
    node.warn(typeof msg.payload);
    if(typeof msg.payload == "object") payload=JSON.stringify(msg.payload);
    else payload=msg.payload;
    client.publish(msg.topic,payload);
};
context.global.closeclient=function(){
    client.end();
};

client.on('message', function (topic, message) {
    // message is Buffer
    payload=message.toString();
    if(payload=="close") client.end();
    else node.warn(message.toString());
    //client.end();
});
client.on('close', function () {
    node.warn("client disconnected");
});
return null;

My issue here is, once I deploy again, the prior client already running keeps doing so. So when I publish on the topic "test/test/test" I get the same message times the number of times I deployed after startup (I inject everytime nodered deploys)

Could anybody help, please? Thank you in advance.

EDIT: After solving this issue, this is the function node I get

node.status({fill:"red",shape:"ring",text:"disconnected"});
require = global.get('require');
var mqtt = require('mqtt');
client  = mqtt.connect('mqtt://test.mosquitto.org');

/*I made these functions in order to be able to publish messages or close the client from every function node*/
context.global.publish=function(msg){
    node.warn(typeof msg.payload);
    if(typeof msg.payload == "object") payload=JSON.stringify(msg.payload);
    else if(typeof msg.payload == "number") payload=msg.payload.toString(10);
    else payload=msg.payload;
    client.publish(msg.topic,payload);
};
context.global.closeclient=function(){
    client.end();
};

/*Client events*/
client.on('connect', function () {
    node.warn("Connected. ClientID: " + client.options.clientId);
    client.subscribe('presence', function (err) {
        if (!err){
            node.warn("subscribed to 'presence'");
            context.global.publish({topic:'presence', payload:'Hello mqtt'});
            node.status({fill:"green",shape:"dot",text:"connected"});
        }
        else node.error(err);
    });
});
client.on('message', function (topic, message) {
    // message is Buffer
    payload=message.toString();
    if(payload=="close"){
        node.warn("close");
        context.global.closeclient();
    }
    node.send({topic:topic,payload:payload});
    //client.end(); I don't want the client to end right away
});
client.on('close', function () {
    node.status({fill:"red",shape:"ring",text:"disconnected"});
    node.warn("cliente desconectado");
});

/*Node implemented in order to detect a deployment, it shuts down the client. Otherwise the client keeps subscribed and running even after a deploy*/
node.on('close', function() {
    node.warn("Deploy, closeclient");
    context.global.closeclient();
});

return null;
1 Like

Can I ask why you don't use the MQTT nodes?

in your close function you are just saying disconnected... you aren't actually disconnecting.

Sure, that is because I would like to dynamically change the ID of the MQTT client

Yeah, I copypasted while trying different things and forgot to uncomment that part in particular. But the issue here is how to close the client once I deploy again

Edit: Sorry, I misunderstood the message. Anyway on the event "close" the client is already closing, there is no need to close it again. That part is only for when the client is already closed, it only shows "I am disconnected"

You need to add a handler on the 'close' event of the node object as described here: https://nodered.org/docs/user-guide/writing-functions#tidying-up

Thank you very much, this was exactly the thing I was looking for! :slight_smile:

Could you publish your function node when you get it working as I think a few people are interested in ability to dynamically change MQTT connections

Sure, the function node is after the "EDIT" in the OP

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.