javascriptnode.jsmqttmessagebrokeremq

How to subscribe to all topics/messages using NodeJS mqtt, emqx


I am writing an MQTT subscriber in NodeJS using the mqtt package. The goal of this subscriber is to receive all messages coming to any/all topics but looks like the subscription to # (subscribe to all topics) does not seem to work. But when I replace # with an actual topic name it seems to work fine. Not sure why it is not working.

PS: the broker I am using is emqx.

Here is the code below.

const mqtt = require('mqtt');

const TOPIC = '#';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 1883;
const USERNAME = process.env.USERNAME || 'username';
const PASSWORD = process.env.PASSWORD || 'password';
const PROTOCOL = 'mqtt';

const clientOption = {
    port: PORT,
    host: HOST,
    username: USERNAME,
    password: PASSWORD,
    protocol: PROTOCOL
};
const client  = mqtt.connect(clientOption);
console.log(`Connecting to mqtt://${HOST}:${PORT}@${USERNAME} topic:${TOPIC} ...`);

client.on('connect', function () {
  console.log(`Connected!`);

  client.subscribe(TOPIC, function(err) {
    if(err) {
      console.error(err);
    } else {
      console.log(`Subscription to ${TOPIC} successful.`);
    }
  });

  client.on('message', function (topic, message) {
    // message is Buffer
    console.log(`Incoming message to topic = ${topic} ...`);
    console.log(message.toString());

    console.log('Preparing outbound message');
    const outboundMsg = {...message, source: topic}
    console.log('Outbound message below');
    console.log(outboundMsg);
  });

});

Solution

  • Figured out the problem.

    The issue was, I was running emqx inside a docker container, and emqx by-default blocks publishing and subscribing to $SYS/# and # topics.

    This can be overridden in the etc/acl.conf file.

    EMQX ACL DOCS