JavaScript
Node.js
Express
websocket
mqtt

Node.jsでMQTTブローカーを立てて、ブラウザから確認する

Nefry BT(ESP32)でMQTTを使ってみよう Subscribe編などでMQTT実装をNode.jsで試してみましたが、Web側で情報を受け取るためにはBrokerサーバーにHTTPサーバーも載せて実装する必要があります。

MQTT over Websocketsなどを参考に作ってみました。

Broker+Webサーバーの準備

Webサーバー(のフレームワーク)としてexpress、Brokerサーバーとしてmoscaを利用します。

npm i --save express mosca
broker.js
'use strict';

const express = require("express");
const http = require('http');
const mosca = require('mosca');

const HTTP_PORT = 3000;
const MQTT_PORT = 1883;

const app = express();
const httpServer = http.createServer(app);
const broker = new mosca.Server({port: MQTT_PORT});

broker.on('ready', () => console.log('Server is ready.'));
broker.on('clientConnected', client => console.log('broker.on.connected.', 'client:', client.id));
broker.on('clientDisconnected', client => console.log('broker.on.disconnected.', 'client:', client.id));
broker.on('subscribed', (topic, client) => console.log('broker.on.subscribed.', 'client:', client.id, 'topic:', topic));
broker.on('unsubscribed', (topic, client) => console.log('broker.on.unsubscribed.', 'client:', client.id));
broker.on('published', (packet, client) => {
    if (/\/new\//.test(packet.topic))return;
    if (/\/disconnect\//.test(packet.topic))return;
    console.log('broker.on.published.', 'client:', client.id);
});

app.get('/',(req,res) => res.sendfile('./index.html'));

broker.attachHttpServer(httpServer);
httpServer.listen(HTTP_PORT);

これで起動すると、 1883ポートでBrokerサーバーが起動しつつ、そこでPubliserから受けたパケットは3000ポートで待ち受けてるWebSocket側にも配信(Subscribe)されます。

ブラウザ側 (Subscriber)

ブラウザ側ではWebSocketを内部利用しつつ、MQTTのインターフェイスでアクセスできます。ブラウザ側が受信機能(Subscriber)になります。

mqtt.jsを読み込ませます。

https://unpkg.com/mqtt/dist/mqtt.min.jsにアクセスすると最新のバージョンが表示されるので、参照しましょう。

index.html
<html>
    <head>
        <title>websocket</title>
    </head>
    <body>
        <script src="https://unpkg.com/mqtt@2.15.1/dist/mqtt.min.js"></script>
        <script>

        const client = mqtt.connect();
        client.subscribe("n0bisuke");

        client.on("message", (topic, payload) => {
            console.log(topic,payload.toString('utf-8'));
        });

        client.publish("mqtt/demo", "hello world!");

        </script>
    </body>
</html>

n0bisukeトピックに送られた情報をコンソールに表示します。

Publisher(おまけ)

Publisher側は何か適当に用意すれば良いですが。Node.jsでやる場合はこんな感じです。

npm i --save mqtt
publisher.js
'use strict';

const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://localhost');

client.on('connect', () => console.log('publisher.connected.'));

setInterval(() => {
    const message = Date.now().toString();
    client.publish('n0bisuke', message);
    console.log('publisher.publish:', message);
}, 1000);

n0bisukeトピックに毎秒情報を送信します。

動作

こんな感じでNode.js側でPublishした情報がBrokerを経由してブラウザ側で受け取れてました。

意外と情報が無いですが、これできるとMQTTの利用の幅が広がって便利です。