سؤال

So I have a node application that makes use of MQTT. I want to encapsulate all my MQTT client creation logic in a single place to ease refactoring. I wrote a moudel that looks like the following:

var mqtt = require('mqtt')
, host = 'localhost'
, port = '1883';

var settings = {
    keepalive: 30000,
    protocolId: 'MQIsdp',
    protocolVersion: 3,
    username:'testuser',
    password:'testpass'
}

exports.createClient = function(clientId){
    if(clientId){
        settings.clientId = clientId;
    }//otherwise default

    return mqtt.createClient(port, host, settings);
}

I'm pretty new to node and would say I have intermediate javascript programming skills. For whatever reason, whenever I run this code with multiple client creation, all hell breaks loose. They don't play nice and kick each others connections.

However, If I put the exact same code directly in each file, there are no issue. One of the more experienced node developers on the team said that it might be something with the way node caches user modules? That the code actually does not return a new client instance whenever create client is called multiple times.

How can I rewrite this simple factory to function correctly?

هل كانت مفيدة؟

المحلول

The problem is that you share settings, but also modify them on each call. This can help:

var mqtt = require('mqtt')
, host = 'localhost'
, port = '1883';

exports.createClient = function(clientId){
    var settings = {
        keepalive: 30000,
        protocolId: 'MQIsdp',
        protocolVersion: 3,
        username:'testuser',
        password:'testpass'
    }

    if(clientId){
        settings.clientId = deviceId + '-' + clientId;
    }

    return mqtt.createClient(port, host, settings);
}

Also you need to get deviceId from arguments or some other legit place

نصائح أخرى

// requires up here
module.exports = function (options) {
   var settings = {
       keepalive: options.keepalive,
       protocolId: options.protocolId,
       protocolVersion: options.protocolVersion,
       username: options.username,
       password: options.password
   };

   return {
       createClient: function (clientID) {
           // your client creation code
       },
       otherMethod: function () {...}

   }
}

See how it all gets wrapped up? When you require this module, you will be getting a function back (an object still of course), example:

var yourMod = require('./yourMod') ({
    keepalive: 30000,
    protocolId: 'MQIsdp',
    protocolVersion: 3,
    username:'testuser',
    password:'testpass'
});

var cliendID = yourMod.createClient ( 23 );

I believe that should work. I have a tracking module that 3 different apps use, and they all connect to different databases. This is the basic module layout I use for it. It's in fact called the module pattern in javascript.

EDIT: Fixed for addressed question.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top