Skip to content

Cannot keep client listening continually. #364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
AdamMiltonBarker opened this issue Dec 27, 2015 · 28 comments
Closed

Cannot keep client listening continually. #364

AdamMiltonBarker opened this issue Dec 27, 2015 · 28 comments

Comments

@AdamMiltonBarker
Copy link

AdamMiltonBarker commented Dec 27, 2015

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
Copy link
Author

AdamMiltonBarker commented Dec 27, 2015

Found my answer here: #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
Copy link
Member

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 #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
#364 (comment).

@4rzael
Copy link
Contributor

4rzael commented Dec 27, 2015

You didn't really change the way you subscribed.

Here is what your first code does:

  • Connect to the server (client.connect)
  • Once connected :
    • Listen to every messages and log them when they come (client.subscribe).
    • Send a message once (client.publish).

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
Copy link
Author

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
Copy link
Contributor

4rzael commented Dec 27, 2015

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
Copy link
Author

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

@mcollina
Copy link
Member

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
Copy link
Author

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
Copy link
Member

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
Copy link
Author

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
Copy link
Author

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

@NancyZY
Copy link

NancyZY commented Oct 31, 2016

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

@AdamMiltonBarker
Copy link
Author

Yes I stopped using this client.

@Harsha-HV
Copy link

Harsha-HV commented Mar 28, 2017

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
Copy link

same problem

1 similar comment
@Rod-O
Copy link

Rod-O commented Feb 25, 2018

same problem

@chinds185a
Copy link

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

@Franco-Poveda
Copy link

@AdamMiltonBarker witch js client library worked for you?

@jigneshk5
Copy link

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
Copy link

ievgennaida commented Jul 23, 2019

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
Copy link

iriekun commented Nov 8, 2019

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

@smitthhyy
Copy link

smitthhyy commented Nov 26, 2019

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
Copy link
Author

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

@AdamMiltonBarker
Copy link
Author

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

@smitthhyy
Copy link

@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
Copy link
Author

@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
Copy link

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 #1001 this one was reproduced.

Workaround: don't use QOS 2.

@shre2398
Copy link

shre2398 commented Jan 29, 2021

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests