BogisW
BogisW

Reputation: 473

nodejs mqtt immediately sends disconnect to broker after receiving first messages, should stay subscribed instead

Background

I've set up a mosquitto mqtt broker on my Raspberry Pi. Furthermore, I've a IoT device (Shelly Flood) that sends mqtt packets to the broker, eg. when I water leak is detected.

I want a nodejs script to subscribe to a certain topic, and do some actions, as soon as a message regarding this topic is received by the broker.

Behaviour

I can start the nodejs script and I perfectly receives the last messages that where sent by the IoT devices on the topic. However, I don't receive any updates on these topics, althought they are sent. The obviouos reason according to the mosquitto log is that node js or my script sends a DISCONNECT message to the broker.

nodejs Script

var mqtt = require('/usr/lib/node_modules/mqtt')

const mqttBroker = 'mqtt://192.168.11.19';
const clientId = 'nodejs-mqtt@Raspberry2';
const myTopics = ['#'];

var client  = mqtt.connect(mqttBroker, {clientId:clientId, keepalive:5000, reconnectPeriod: 1000 * 1})

client.on('message', function (topic, message) {
  // message is Buffer
  console.log(topic.toString())
  console.log(message.toString())
  client.end()
})

client.on('connect', function () {
  client.subscribe(myTopics, function (err) {
    if (!err) {
       console.log ('subscribed to ' + mqttBroker + ' for topics ' + myTopics.join(', '));
       // client.publish('/nodejs', 'Hello mqtt')
    }
  })


  console.log('connected to ' + mqttBroker + ' as ' + clientId);

  // 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);
})

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

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

client.on('reconnect', function() {
    console.log("reconnect");
});
# Script output #
connected to mqtt://192.168.11.19 as nodejs-mqtt@Raspberry2
subscribed to mqtt://192.168.11.19 for topics #
shellies/shellyflood-C8A9D2/online
true
shellies/shellyflood-C8A9D2/sensor/temperature
25.12
shellies/shellyflood-C8A9D2/sensor/flood
false
shellies/shellyflood-C8A9D2/sensor/battery
69
shellies/shellyflood-C8A9D2/sensor/error
0
shellies/shellyflood-C8A9D2/sensor/act_reasons
["sensor"]
sending  0
sent  0
sending  1
sent  1
sending  2
sent  2

mosquitto Logs

1624712368: New connection from 192.168.11.19 on port 1883.
1624712368: New client connected from 192.168.11.19 as nodejs-mqtt@Raspberry2 (c1, k5000).
1624712368: No will message specified.
1624712368: Sending CONNACK to nodejs-mqtt@Raspberry2 (0, 0)
1624712368: Received SUBSCRIBE from nodejs-mqtt@Raspberry2
1624712368:     # (QoS 0)
1624712368: nodejs-mqtt@Raspberry2 0 #
1624712368: Sending SUBACK to nodejs-mqtt@Raspberry2
1624712371: Received PUBLISH from nodejs-mqtt@Raspberry2 (d0, q1, r0, m12577, 'test', ... (1 bytes))
1624712371: Sending PUBACK to nodejs-mqtt@Raspberry2 (Mid: 12577)
1624712371: Sending PUBLISH to mosqsub|23437-raspberry (d0, q0, r0, m0, 'test', ... (1 bytes))
1624712371: Sending PUBLISH to nodejs-mqtt@Raspberry2 (d0, q0, r0, m0, 'test', ... (1 bytes))
1624712371: Received DISCONNECT from nodejs-mqtt@Raspberry2
1624712371: Client nodejs-mqtt@Raspberry2 disconnected.
1624712404: Received PINGREQ from mosqsub|23437-raspberry
1624712404: Sending PINGRESP to mosqsub|23437-raspberry

Question

Do you have any idea why my client sends a DISCONNECT to the mqtt broker, or - solution-oriented - what do I have to improve that my client gets to messages belonging to the topics subscribed 'forever' (until the script is stopped manually).

Any help / hints are highly appreciated!

Upvotes: 1

Views: 1754

Answers (1)

cbr
cbr

Reputation: 13662

You're ending the client's connection in the message handler:

client.on('message', function (topic, message) {
  console.log(topic.toString())
  console.log(message.toString())
  
  client.end()
  // ^^^^^^
})

Remove the client.end() call.

Upvotes: 3

Related Questions