Neil
Neil

Reputation: 412

MQTT real time Feed to html page in Node JS

My route mqtt.js contains the following :-

client.on('connect', function () {
    client.subscribe('shmindia');
    client.publish('shmindia', new Date());
    console.log("********************** MQTT STARTED *********************");
});

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

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

router.get('/', function (req, res) {
    /*Render the index.hbs and pass the View Model*/
    var vm = {
        title: 'MQTT',
        message: [new Date(), m]
    }
    console.log(vm.message);
    res.render('mqtt/index', vm);
});

router.get('/getsensordata', function (req, res) {
    var vm = {
    data:m
    };
    res.send(vm);
});

module.exports = router;

The index.hbs contains the following code:-

<div id='container' style="width:100%; height:400px;">

</div>
<script>
    var chart;
    function requestData() {
        $.ajax({
            url: 'http://localhost:1998/mqtt/getsensordata',
            success: function (point) {
                var series = chart.series[0],
                  shift = series.data.length > 20;
                chart.series[0].addPoint(point, true, shift);
                setTimeout(requestData, 1000);
            },
            cache: false
        });
    }
    $(document).ready(function () {
        chart = new Highcharts.Chart({
            chart: {
                renderTo: 'container',
                defaultSeriesType: 'spline',
                events: {
                    load: requestData
                }
            }
    });
</script>

so, in this what happens is, the index file, requests for data and then, some data is retrieved from the server.
what i am expecting is when ever the MQTT client publishes the message, the data should go to the index.hbs
HOW CAN I ACHIEVE THAT ?
EDIT 1: i can use websockets, but i want to hide the link to MQTT server, login details.

Upvotes: 0

Views: 2215

Answers (1)

hardillb
hardillb

Reputation: 59638

Don't use AJAX to get updates, use pure websockets to push updates from the server side to the client when a message is delivered to the server.

Use the express-ws module on the server side, something like this:

var expressWs = require('express-ws')(app); //app = express app 

expressWs.app.ws('/sensordata', function(ws, req){});
var aWss = expressWs.getWss('/sensordata');

client.on('connect', function () {
    client.subscribe('shmindia');
    client.publish('shmindia', new Date());
    console.log("********************** MQTT STARTED *********************");
});


client.on('message', function (topic, message) {
    // message is Buffer 
    m = message;
    aWss.clients.forEach(function (client) {
        client.send(m);
    });
    console.log(message);
   // client.end();
});

And on the webpage side:

<script>
   var ws = new Websocket('ws://localhost:1998/sensordata');
   ws.onmessage = function(message){
     var series = chart.series[0],
     shift = series.data.length > 20;
     chart.series[0].addPoint(message, true, shift);
   } 
</script>

Upvotes: 1

Related Questions