はじめに
HerokuにデプロイされたNode-RED環境でMQTTを試そうと思ったが、CloudMQTTの追加オプションで無料プラン(Cute Cat)が使えなくなっていた。
(厳密には、HerokuのページにはCute Catを選択できるように表示されているが、CloudMQTTのページを見ると有料プラン($5/月)を使えと書かれている。)
Heroku環境はウェブアクセスしか許可されていない。(ポート番号(80/443)のみ開放されている)
MQTT Brokerを使用する場合、ポート番号(1883/8883)が開放されていないため、代替手段としてMQTT over WebSocketを使用する必要がある。
Node-REDのAedes MQTT BrokerはMQTT over WebSocketにも対応しているため、試しにブラウザで利用できるチャットシステムを作ってみた。
Node-REDのMQTT BrokerはMoscaからAedesへ
「Node-REDのMQTT Brokerと言えばMoscaじゃないの?!」と思った方で、MoscaからAedesへ変わった背景について興味がある方はこちらをご覧ください。
Node-REDフロー
Node-REDのフローは非常にシンプルでこれだけです。
MQTT inノード(MQTT Subscribe)とMQTT outノード(MQTT Publish)はテスト用なので、実質的にはAedes MQTT Brokerノードだけで動作します。
Aedes MQTT Brokerノードの設定
WebSocketの設定をします。
- WS Bind → path ・・port(ポート)ではなくpath(パス)を選択します
- WS path → /mqtt ・・任意(他のWebSocketのパスと重複しないようにします)
MQTT inノードとMQTT outノードの設定
サーバとトピックの設定をします。
- サーバ → localhost:1883 ・・サーバはlocalhost、ポートは1883を設定します
- トピック → Test/chat ・・任意(他のMQTTアプリケーションのトピックと重複しないようにします)
「あれ?!MQTT inノードとMQTT outノードはMQTT over WebSocketではなく、MQTT接続でいいの?!」と思うかもしれませんが、Node-REDが動いているノード内での接続(localhost接続)なので、Heroku環境の外部からの接続制限の影響を受けません。
ブラウザのチャットアプリ
MQTT ClientライブラリはPaho MQTT Javascriptライブラリを使用しました。
絵文字も利用可能です。
バージョン1.0.1での問題点
最初によく利用されているバージョン1.0.1を使用して実装しましたが、Heroku環境の外部からの接続制限の影響で、無通信状態だと一定時間で接続が切られる(socketがclosedになる)事象が発生しました。
バージョン1.1.0での注意点
接続が切れた場合に自動で再接続するオプションが追加されたバージョンを試すために、HTMLファイルで読み込むスクリプトのURLを変更し、connectOptionsでreconnectを有効にしたところ、サンプルコードがエラーになりました。
調査したところ、まさに同じ事象に遭遇した情報にたどり着くことができました。
原因はPaho MQTT Javascriptライブラリのバージョンアップで、ネームスペースがPaho.MQTTからPahoへ変わったことでした。(サンプルコードはPaho.MQTT.ClientからPaho.Clientへ書き換えて解決)
"Previously the Client’s Namepsace was Paho.MQTT, as of version 1.1.0 (develop branch) this has now been simplified to Paho."
サンプルコード
ソースコードをGithubに置きました。
バージョン1.1.0のサンプルコードを使用すれば問題ありませんが、参考(差分を確認するため)にバージョン1.0.1のサンプルコードも置いておきます。
- index.html ・・Paho MQTT Javascriptライブラリ (バージョン1.1.0)
- index_old.html ・・Paho MQTT Javascriptライブラリ (バージョン1.0.1)
サンプルコードを使用する場合は、Heroku環境にデプロイしたNode-REDフローのURLを設定してください。
(例. ********.herokuapp.com)
var host = ""; // ホスト名を設定する
2022/5/6 追記
KatacodaでMQTT over WebSocketをチャットで試せるPlaygroundを作りました。