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
'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
にアクセスすると最新のバージョンが表示されるので、参照しましょう。
<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
'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の利用の幅が広がって便利です。