0

I am very new to nodejs and want to push an MQTT client-received message to the server front-end. I have managed to get an MQTT listener that will write received data to the console via console.log, and I also have used express to create a simple server with an index.html page containing a textarea.

However, as I am very new, I do not know how to send the mqtt message over to the front-end. I have tried using a test app.post which can change the html display to a custom message, but it doesn't work if called in the mqtt client.

Right now I'm trying to send the mqtt message into a textbox on the html page.

server.js:

const express = require("express");
const app = express();
var port = process.env.PORT || 1337;

app.listen(port, () => {
    console.log("Application started and Listening on port " + port);
});
app.use(express.static(__dirname));

app.get("/", (req, res) => {
    res.sendFile(__dirname + "/Views/index.html");
    console.log(__dirname + "/index.html");
});

app.post("/", (req, res) => {
    res.send("Thank you for subscribing");
});
////'use strict';

var mqtt = require('mqtt');
var client = mqtt.connect("mqtt://192.168.0.165", { port: 1883, clientId: "test1", username: "admin", password: "mypassword" });
client.on("connect", function () {
    console.log("connected  " + client.connected);
});
client.subscribe("KSPL/devices/me", { qos: 0 });
client.on("message", (topic, message) => {
    const buff = Buffer.from(message, "utf-8");
    const msg = buff.toString();
    console.log(msg);
    console.log(app);
    app.post("/", (req, res) => {
        res.send(msg);
    });
});

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="../server.css" rel="stylesheet" />
    <link rel="stylesheet"
          href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css">
    <title>html form</title>
</head>
<body>
    <div class="subscribe-container">
        <form method="POST" style="display:flex;">
            <textarea name="mytextarea" style="width:100%"></textarea>
        </form>
    </div>
</body>
</html>

It should ideally push into the html's textarea when the MQTT receives a message, like this: (https://i.stack.imgur.com/r62rR.png)

gre_gor
  • 6,669
  • 9
  • 47
  • 52
  • So if I read your code correctly you want to "post" the message to the client-frontend with app.post when the mqqt-client.on(message) is invoked? Because what you are doing now is you register a new app.post with path "/" every time a message is recieved from the mqtt broker and the the post ist called it sends the message that was last recieved. Is that intended? – h0p3zZ Aug 30 '23 at 01:00
  • I don't intend to make a new app.post with path "/" but I'm new to nodejs and don't quite understand how this works. I'm trying to post the message to client frontend but am not sure what's the function to do so. – Nx Cloud Test 2021 Aug 30 '23 at 01:30
  • Does this answer your question? [How to use server-sent-events in express.js](https://stackoverflow.com/questions/34657222/how-to-use-server-sent-events-in-express-js) – gre_gor Aug 30 '23 at 20:31

1 Answers1

1

The short answer here is, you don't.

You are trying to map an asynchronous protocol (MQTT) to a synchronous one (HTTP). Without a detailed understanding of what this means, it is very hard to do. You are also trying to map a push action (MQTT broker sending new messages) to a pull action (web browser requesting page updates with HTTP GET/POST requests).

A much better solution is to ensure that the MQTT broker supports MQTT over WebSockets and then run a JavaScript MQTT client actually in the the web page so it can directly subscribe to topics and then update the page however you want when messages are delivered.

You can use either the Paho client or the MQTT.js client in the page.

hardillb
  • 54,545
  • 11
  • 67
  • 105