🧊

ブラウザでもMQTTでメッセージングしたい!

調べたついでにメモを書き残します。

結局ブラウザでしか動かさないもののために、あえてMQTTを使う理由は私にはわかりません・・。

そもそもMQTTとは

これは調べたほうがはやいです。

MQTT コトハジメ · GitHub
MQTTについてのまとめ — そこはかとなく書くよん。

WebSocket

唐突に出しましたが、ブラウザに直接MQTTを扱う仕組みがないので、WebSocketに乗せてメッセージングするのが今のとこ常套手段ぽい。
まぁI/Oの話なので知っておく程度で良いのでは。

サーバーサイド

いわゆるBrokerサーバーです。

外部サーバーを利用する

商用サービスとかOSSとかいろいろありますが、さくっと試すならこれが良さげ。

test.mosquitto.org

  • mqtt://test.mosquitto.org:1883
  • ws://test.mosquitto.org:8080

ありがたや・・。

自分でサーバーを立てる

もちろん自分でサーバーを用意することもできます。

いろいろ調べたのですが、最終的に行き着いたのがコレ。

mcollina/mosca · GitHub

var mosca = require('mosca');
var http  = require('http');

// WebSocket用
var httpServ = http.createServer();
// MQTT用
var mqttServ = new mosca.Server();

mqttServ.attachHttpServer(httpServ);
httpServ.listen(3000);

// あとはお好きに
mqttServ.on('clientConnected', fn);
mqttServ.on('published', fn);
mqttServ.on('subscribed', fn);

この例では別で用意したサーバーをattachしてますが、Mosca内サーバーを使うことも可能。
コードを書かなくても、ワンライナーコマンドラインからサクッと立てることもできます。

npm install mosca bunyan -g
mosca -v --http-port 3000 --http-bundle --http-static ./ | bunyan

便利な世の中だわ・・。

ちなみにサーバーAPIのドキュメントはコレ。

Mosca

サーバーが動いてるかどうかは、wscatとかでチェックすると良いと思います。

クライアントサイド

サーバーが用意できたところでクライアントです。
MQTT.jsというのを使います。

mqttjs/MQTT.js · GitHub

MOWS

ちなみに、"MQTT WebSocket"とかで検索するとちょいちょい出てくるMOWSってライブラリですが・・。
コレ、MQTT.jsがメジャーアップデートされたタイミングで、WebSocketのサポートもMQTT.js側でやるようになって、depricatedになったそうですよ。

途中まで気付かなかったのでいちおう。

browserMqtt.js

さて、このMQTT.jsはNode向けに書かれてるので、ブラウザで使うためには一手間必要です。
そう、みんな大好きBrowserifyで変換しないといけません。

そのためにcloneしてinstallして・・めんどくせーって人のために、バージョン1.3.5の出力結果をGistにご用意しました。

https://gist.github.com/leader22/87350894dbe552f4c94a

あとはコードを

// <script src="browserMqtt.js"></script>

// 接続(WebSocketなBrokerへのURL)
var client = mqtt.connect('ws://test.mosquitto.org:8080');

// 購読するTopicを指定
client.subscribe('mqtt/demo');

client.on('message', function(topic, payload) {
  console.log([topic, payload].join(': '));
  // 切断
  client.end();
});

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

簡単!

コード書いててハマったところ

server.on(clientConnected)でpublish

しても届いてくれない。
このconnectの瞬間では早すぎで、その後のsubscribedとかでpublishしてあげないとダメ。

packet.payloadは

toStringして使うべし。

おわりに

商用でやるならメッセージの暗号化とかQoSがどうとかいろいろ気にしないといけないんでしょうが、さっくり試す場合や気軽に使える状況ならこんなもんでも良さそうです。
書いた感じはSocket.IOとかとほぼ一緒で、すぐわかると思います。

ただ、結局ブラウザでしか動かさないもののために、あえてMQTTを使う理由ってなんかあるんやろうか・・。