mqttjs / MQTT.js

The MQTT client for Node.js and the browser
Other
8.54k stars 1.41k forks source link

Cannot keep client listening continually. #364

Closed AdamMiltonBarker closed 8 years ago

AdamMiltonBarker commented 8 years ago

I am using mqtt.js and have an issue that I haven't experienced before when using a python MQTT client. When subscribed to a client using the code below I receive one message back and then it will not receive any further messages, I have Googled all night to try and see how to do equivalent of loop_forever or loop_start but cannot find the documentation anywhere, please could you point me in the right direction.

var mqtt = require('mqtt');

var settings = {
  keepalive: 1000,
  clientId: appData.deviceType+appData.deviceID,
  username: appData.mqttUser,
  password: appData.mqttPassword
}

var mqtt    = require('mqtt');
var client  = mqtt.connect('mqtt://'+appData.mqttLoc, settings);

client.on('connect', function () {
  client.subscribe('presence');
  client.publish('presence', 'Hello mqtt');
});

client.on('message', function (topic, message) {
  console.log(message.toString());
});
AdamMiltonBarker commented 8 years ago

Found my answer here: https://github.com/mqttjs/MQTT.js/issues/352

This is the correct way to continually check for latest messages? Wasn't sure if you needed to continually subscribe.

var mqtt = require('mqtt');

var settings = {
    clientId: appData.deviceType+appData.deviceID,
    username: appData.mqttUser,
    password: appData.mqttPassword,
    keepalive: 1,
    clean: false,
    reconnectPeriod: 1000 * 1
}

var mqtt    = require('mqtt');
var client  = mqtt.connect('mqtt://'+appData.mqttLoc, settings);

client.on('connect', function () {
    console.log('connected to the server. ID :', appData.deviceType+appData.deviceID);
});

client.on('message', function (topic, message) {
  console.log(message.toString());
});

client.on("error", function(error) {
    console.log("ERROR: ", error);
});

client.on('offline', function() {
    console.log("offline");
});

client.on('reconnect', function() {
    console.log("reconnect");
});

setTimeout(function(){
   client.subscribe('test', { qos: 1 }); 
}, 3000)

//start sending
var i = 0;
setInterval(
    function(){
        var message = i.toString();
        console.log("sending ", message)
        client.publish("test", message, {qos: 1}, function(){
            console.log("sent ", message)
        });
        i += 1;
    },
3000)
mcollina commented 8 years ago

I'm not understading your question. MQTT.js will emit the message event when something arrives. There is no need for loop_start or loop_forever, node.js has a reactor pattern built in. Il giorno dom 27 dic 2015 alle 17:47 AdamMiltonBarker < notifications@github.com> ha scritto:

Found my answer here: #352 https://github.com/mqttjs/MQTT.js/issues/352

This is the correct way to continually check for latest messages? Wasn't sure if you needed to continually subscribe.

— Reply to this email directly or view it on GitHub https://github.com/mqttjs/MQTT.js/issues/364#issuecomment-167425688.

4rzael commented 8 years ago

You didn't really change the way you subscribed.

Here is what your first code does:

And you see only one message, which is normal because you only send one. (By the way, if another client sent some presence packet, you would receive them).

In the second one, you send packets every 3 seconds, so... Yeah, you receive many of them, which is the expected behaviour too.

In short, what you're doing in the second code is not checking for new messages, but sending many of them.

Anyway, your first code should work correctly. In order to test it, run it, and while it's running, run a second one with this:

var mqtt = require('mqtt');

var settings = {
    clientId: appData.deviceType+appData.deviceID,
    username: appData.mqttUser,
    password: appData.mqttPassword,
    keepalive: 1,
    clean: false,
    reconnectPeriod: 1000 * 1
}

var client  = mqtt.connect('mqtt://'+appData.mqttLoc, settings);

client.on('connect', function () {
    console.log('connected to the server. ID :', appData.deviceType+appData.deviceID);

    // send packets
    var i = 0;
    setInterval(
        function(){
            var message = i.toString();
            console.log("sending ", message)
            client.publish("test", message, {qos: 1}, function(){
                console.log("sent ", message)
            });
            i += 1;
        },
    3000)
});

You should see new packets beeing printed on the first client.

AdamMiltonBarker commented 8 years ago

Hi thanks for the reply.

No with the first script I connect to an existing server that has messages published to it constantly and the script did not receive those comments at all, at first it had client.end in it so the script shutdown after the message received. I removed that but it still did not receive the messages where all of my existing python clients were, hence why I thought we needed similar to python loop_start or loop_forever, I am not new to MQTT only with node js I currently have a full network of devices set up using python MQTT libraries (paho), I have a MOSQUITTO broker set up but am looking to replace all the python with this node js eg, swap my python clients for MQTT.js clients and replace the broker with the server example, I am doing this as I have worked a way of letting devices confirgure themselves and the server making my devices plug in and go for customers also Azure IoT hub doesn't have a python library.

With the second script I can now receive the messages but this requires subscribing in a loop, I wasn't aware you had to keep subscribing I thought once you had subscribed you were subscribed so I was asking for confirmation that this is the correct way.

I understand that the second code is sending multiple messages this is for test, but I removed that and with the loop now subscribing multiple times I can receive all the messages sent from other clients but I am not sure this is the correct way.

From your comments it seems like the first script should receive all the messages sent to that topic without the loop but this is not the case, with client.end() after the message is received the node script will end, without it it just hangs.

This is what allowed me to receive all the messages from the topic, without this it will receive 1 message from the publish in the script and then it will just hang.

setTimeout(function(){ client.subscribe('test', { qos: 1 }); }, 3000)

4rzael commented 8 years ago

Oh, yeah, my bad. I didn't see the re-subscribing loop.

That's strange, you shouldn't need to re-subscribe. Are you sure the packets you want to listen to were sent on the topic presence ?

What version of mqtt.js are you using ?

AdamMiltonBarker commented 8 years ago

They were sent to the correct topics yes, just installed it yesterday so what ever NPM install has at the moment.

mcollina commented 8 years ago

This works on my box with mosquitto:

var mqtt = require('mqtt');

var settings = {
    clientId: 'abcde',
    clean: false,
    reconnectPeriod: 1000 * 1
}

var mqtt    = require('mqtt');
var client  = mqtt.connect(settings);

client.on('connect', function () {
    console.log('connected to the server');
   client.subscribe('test', { qos: 1 });
});

client.on('message', function (topic, message) {
  console.log('received', message.toString());
});

client.on("error", function(error) {
    console.log("ERROR: ", error);
});

client.on('offline', function() {
    console.log("offline");
});

client.on('reconnect', function() {
    console.log("reconnect");
});

//start sending
var i = 0;
setInterval(
    function(){
        var message = i.toString();
        console.log("sending ", message)
        client.publish("test", message, {qos: 1}, function(){
            console.log("sent ", message)
        });
        i += 1;
    },
3000)

I might guess that your keepalive is way to small, possibly your broker is on the net and 1s is not enough.

Which broker are you using?

AdamMiltonBarker commented 8 years ago

It also works for me as there is a loop keeping the script running, I had a higher keepalive at first 1000, initially I was using Mosquitto broker as I said all of my existing clients that are Python work fine, at the moment I am using the Node JS server example the code that is not working is the code in the first post as I explained it,

I am using mqtt.js and have an issue that I haven't experienced before when using a python MQTT client. When subscribed to a client using the code below I receive one message back and then it will not receive any further messages, I have Googled all night to try and see how to do equivalent of loop_forever or loop_start but cannot find the documentation anywhere, please could you point me in the right direction.

var mqtt = require('mqtt');

var settings = {
  keepalive: 1000,
  clientId: appData.deviceType+appData.deviceID,
  username: appData.mqttUser,
  password: appData.mqttPassword
}

var mqtt    = require('mqtt');
var client  = mqtt.connect('mqtt://'+appData.mqttLoc, settings);

client.on('connect', function () {
  client.subscribe('presence');
  client.publish('presence', 'Hello mqtt');
});

client.on('message', function (topic, message) {
  console.log(message.toString());
});

Additional info is the other clients in Python work fine on both the Mosquitto broker and the server example, without the loop at the bottom the script just terminates after publishing, the messages being sent to the same topic from the python clients/broker are not received and the script does not continue to listen it just ends.

mcollina commented 8 years ago

This works fine as well:


var mqtt = require('mqtt');

var settings = {
  keepalive: 1000
}

var mqtt = require('mqtt');
var client = mqtt.connect(settings);

client.on('connect', function () {
  client.subscribe('presence');
  client.publish('presence', 'Hello mqtt');
});

client.on('message', function (topic, message) {
  console.log(topic, message.toString());
});

there is no need for loop_forever in node.js and MQTT.js. It's an asynchronous platform and it just works.

The problem lies in your broker, not in MQTT.js. MQTT is a complex protocol, and you should use mosca or aedes as your broker if you want to plug in some node.js behavior. For this reason we are deprecating the server implementation here in v2, see #345. There is also https://github.com/mqttjs/mqtt-stack.

AdamMiltonBarker commented 8 years ago

Sorry but you are wrong there is nothing wrong with the broker, the broker works fine with every other type of client I have running and has worked fine for a long time. The issue is the code above is not correct. My broker is Mosquitto.

AdamMiltonBarker commented 8 years ago

As I mentioned I am not new to MQTT, the above code is not working it is not receiving messages.

NancyZY commented 7 years ago

@AdamMiltonBarker Have you solved the problem? I meet too.

AdamMiltonBarker commented 7 years ago

Yes I stopped using this client.

Harsha-HV commented 7 years ago

I have few issues in connecting to MQTT Broker (RabbitMQ) which is installed locally, and trying to create the scripts from the TruAPI, and below is my code and its Output

'use strict';

exports = module.exports = function (vuser) {

  exports=module.exports = function(MQTT)  {     

//var vuserId;
var client;

/* init action */
vuser.init('Vuser init action', function (svc, done) {
  svc.logger.info('Vuser %s init', vuserId);

  mqtt=require('mqtt');
  client= mqtt.connect('http://localhost:15672');
  done();
});

/* main action */
vuser.action('Vuser main action', function (svc, done) { 
  svc.logger.info('Vuser %s running', vuserId);
  svc.transaction.start('PUBLISH_MQTT');

  svc.logger.info('publishing message');   
  client.publish('HPE/MQTT_TEST','HELLO SRL MQTT PROTOCOL'); 
  svc.transaction.end('PUBLISH_MQTT',svc.transaction.pass);

  client.on('message', function(topic, message) {
    svc.logger.info('publisher-putting message');
    console.log(message.tostring());
  });
});  

OUTPUT:

D:\Projects\Whitepapers\MyTruAPI\PublisherScript>truapi-cli
2017-03-28T11:30:18.716Z - debug:   TruAPI CLI started
2017-03-28T11:30:18.948Z - debug:   load json from D:\Projects\Whitepapers\MyTru
API\PublisherScript\truapi.json
2017-03-28T11:30:18.948Z - debug:   load script {"script":"D:\\Projects\\Whitepa
pers\\MyTruAPI\\PublisherScript\\dempsample.js","testId":"localtest","groupId":"
localGroup"}
2017-03-28T11:30:18.948Z - debug:   script D:\Projects\Whitepapers\MyTruAPI\Publ
isherScript\dempsample.js loaded
2017-03-28T11:30:18.958Z - debug:   vusers subscribe
2017-03-28T11:30:18.958Z - debug:   vuser 0 subscribed
2017-03-28T11:30:18.958Z - debug:   vusers init
2017-03-28T11:30:18.958Z - debug:   vuser 0 (Init) end
2017-03-28T11:30:18.958Z - debug:   vuser 0, begin Action
2017-03-28T11:30:18.958Z - debug:   vuser 0 (Action) end
2017-03-28T11:30:18.958Z - debug:   vuser 0, begin Action=(1)
2017-03-28T11:30:18.958Z - debug:   vuser 0 (End) end
2017-03-28T11:30:19.967Z - info:    Test finished ( 1.261 s )

PLease help me in moving forward with the above script

Franco-Poveda commented 6 years ago

same problem

Rod-O commented 6 years ago

same problem

chinds185a commented 6 years ago

same problem here, using with cloudMQTT I always receive the message I published when i connected and thats it.

Franco-Poveda commented 6 years ago

@AdamMiltonBarker witch js client library worked for you?

jigneshk5 commented 5 years ago

Yes I stopped using this client. Which javascript client you prefer...I am working with paho python client so far but this client has some major issue with keepalive...Please guide

ievgennaida commented 5 years ago

I have the same problem. 3.0.0 @mcollina could you please check, it's easy to reproduce:


var mqtt = require('mqtt');

var settings = {
  keepalive: 30
}

var mqtt = require('mqtt');
var client = mqtt.connect(settings);

client.on('connect', function () {
  client.subscribe('presence');
  client.publish('presence', 'Hello mqtt');
});

client.on('message', function (topic, message) {
  console.log(topic, message.toString());
});

You have to turn off and on mosca! After that client is there but subscriptions are lost.

I have tried to subscribe with QoS2 and resubscribe: true, clean: false and nothing helped.

Could you please check that?

iriekun commented 4 years ago

I'm having the same issue. Has anyone been able to solve this?

smitthhyy commented 4 years ago

For those that it doesn't work for, it does. Connect to my Mosquitto server using both TLS1.2 and plain mqtt using the following:

var settings = { keepalive: 1000, clientId: 'RANDOM_CLIENT_STRiNG_hERE', username: 'YOUR_BROKER_USERNAME', password: 'YOUR_BROKER_PASSWORD', port: 1883 }

var mqtt = require('mqtt'); var client = mqtt.connect('mqtt://mqtt.broker.domain.address.here', settings);

client.on('connect', function () { client.subscribe('presence'); client.publish('presence', 'Hello mqtt'); });

client.on('message', function (topic, message) { console.log(message.toString()); });

MQTT.JS Version I'm using is "mqtt": "^3.0.0",

AdamMiltonBarker commented 4 years ago

@smitthhyy I would hope it does work by now as I made this post nearly 5 years ago :)

AdamMiltonBarker commented 4 years ago

@smitthhyy it's ok I was playing no offence meant.

smitthhyy commented 4 years ago

@smitthhyy I would hope it does work by now as I made this post nearly 5 years ago :)

It wasn't for you, but those that followed in the last year or so and those still to follow to suggest they look at their code :)

AdamMiltonBarker commented 4 years ago

@AdamMiltonBarker witch js client library worked for you?

I only use websockets now with JS, here is my code, I haven't updated it for a long time nor used it for a long time, if anyone has any problems please let me know through issues. Incidentally there are a lot of examples using my own platform (iotJumpWay) on those repos if anyone finds them useful.

https://github.com/iotJumpway/JumpWayWebsockets

ievgennaida commented 4 years ago

For those that it doesn't work for, it does. Connect to my Mosquitto server using both TLS1.2 and plain mqtt using the following:

var settings = { keepalive: 1000, clientId: 'RANDOM_CLIENT_STRiNG_hERE', username: 'YOUR_BROKER_USERNAME', password: 'YOUR_BROKER_PASSWORD', port: 1883 }

var mqtt = require('mqtt'); var client = mqtt.connect('mqtt://mqtt.broker.domain.address.here', settings);

client.on('connect', function () { client.subscribe('presence'); client.publish('presence', 'Hello mqtt'); }); client.on('message', function (topic, message) { console.log(message.toString()); });

MQTT.JS Version I'm using is "mqtt": "^3.0.0",

I have the issue when subscription completely lost and client does not listening anymore when QOS2 is used! Check this thread https://github.com/mqttjs/MQTT.js/issues/1001 this one was reproduced.

Workaround: don't use QOS 2.

shre2398 commented 3 years ago

@mcollina I am trying to publish messages continuously using follwing code

const topic = "s/us";
var options = {
    clientId: clientId,
    username: username,
    password: password,
};
var temperature = 25;

// connect the client to Cumulocity
try {
    const client = mqtt.connect(serverUrl, options);

    // once connected...
    client.on('connect', function () { // When connected
        console.log('Client Connected');

        // publish a message to a topic
        setInterval(function () {
            console.log("Sending temperature measurement: " + temperature + "º");
            client.publish(topic, temperature.toString());
            temperature += 0.5 - Math.random();
        }, 300);
    });
} catch (err) {
    console.log(err);
}

and subscribing it using the code :

var options = {
  clientId: clientId,
  username: username,
  password: password,
};

const mqttClient = mqtt.connect(serverUrl, options);

// connect the client to Cumulocity
try {

  mqttClient.on('connect', function () { // When connected
    console.log('Client connected');
    //subscribe to a topic
    mqttClient.subscribe(topic, function () {
      mqttClient.on('message', function (topic, message, packet) {
        console.log("Received '" + message + "' on '" + topic + "'");
      });
    });
  });

} catch (err) {
  console.log(err);
}

But I am not able to subscribe messages. Can you please help?