简体   繁体   中英

Subscription to MQTT broker and get the data being passed

I am generating data with a node.js simulator and passing this data to a http route /simulator/data

In the application I am listening broker with MQTT mqtthandler.js file which I share below.

//This is mqtthandler.js file

const mqtt = require("mqtt");

class MqttHandler {
  constructor() {
    this.mqttClient = null;
    this.host = "mqtt://localhost:1883";
    this.username = "YOUR_USER"; // mqtt credentials if these are needed to connect
    this.password = "YOUR_PASSWORD";
  }

  connect() {
    // Connect mqtt with credentials (in case of needed, otherwise we can omit 2nd param)
    this.mqttClient = mqtt.connect(this.host, {
      username: this.username,
      password: this.password,
    });

    // Mqtt error calback
    this.mqttClient.on("error", (err) => {
      console.log(err);
      this.mqttClient.end();
    });

    // Connection callback
    this.mqttClient.on("connect", () => {
      console.log(`mqtt client connected`);
    });

    // mqtt subscriptions
    this.mqttClient.subscribe("value", { qos: 0 });

    // When a message arrives, console.log it
    this.mqttClient.on("message", function (topic, message) {
      console.log(message.toString());
    });

    this.mqttClient.on("close", () => {
      console.log(`mqtt client disconnected`);
    });
  }

  // Sends a mqtt message to topic: mytopic
  sendMessage(message) {
    this.mqttClient.publish("value", message);
  }
}

module.exports = MqttHandler;

When simulator sending the data to the /simulator/data route, I am getting the value and sending the broker with value topic. I share the post request code and output of simulator below.

var mqttHandler = require("../mqtthandler");

module.exports = function (app) {
  app.get("/simulator", function (req, res) {
    res.render("iot/simulator");
  });

  // route to display all the data that is generated
  app.get("/simulator/data", require("./controllers/data").all);

  var mqttClient = new mqttHandler();
  mqttClient.connect();

  // route to write data to the database
  app.post(
    "/simulator/data",
    require("./controllers/data").write,
    (req, res) => {
      mqttClient.sendMessage(req.body.value);
      res.status(200).send("Message sent to mqtt");
    }
  );

  // delete the data when the stream is stopped or when the app is closed
  app.get("/simulator/data/delete", require("./controllers/data").delete);
};

When I send get request to /simulator/data I am able to see generated data, however this data is not being sent to broker.

//This is output of simulator

    [
        {
            "_id": "5ecfadc13cb66f10e4d9d39b",
            "value": "1.886768240197795",
            "__v": 0,
            "categories": []
        },
        {
            "_id": "5ecfadc23cb66f10e4d9d39c",
            "value": "7.351404601932272",
            "__v": 0,
            "categories": []
        }
    ]

PS: Broker is created via node-red

I would like to pass this data to broker and see the result with MQTT subscription. However I can not find where am I making mistake.

Your solution is to fix your development process. Rather than working from failure debugging 2 subsystems (your publisher / simulator and your subscriber), work from success:

1) use publishers that you KNOW work, eg. mosquitto_pub, any simulator that works, etc.

2) use subscribers that you KNOW work, eg. mosquitto_sub

This will solve your problem in minutes, rather than hours or days, and let you focus on the code that you REALLY want to develop.

So a couple of things to look at here.

  1. Your this.mqttClient.subscribe() call is inline with your connect() , on.("error",...) , on.("message",...) etc. So the subscribe() could fire before the connect() has finished...and thus you will never subscribe. Put the subscribe() inside the connect() block.

  2. You are subscribing to "value", which is not a proper MQTT topic. If you must, use value/# for the subscribe(), and "value/.." for the publish(). Your class only allows for the single, hard-coded topic, so won't be very useful when you want to reuse that class for other projects. Take the time now to pass the topic string to the class as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM