2022年の秋にAWS IoT Core
でMQTT
を使用してから、もう少し使用してみようかなと思い、自分の開発環境にも入れてみようかなと思っていました。ただ、最近はWindowsのアプリのインストールではなくDockerを使用してコンテナ環境を作って他の環境でもすぐに使えるようにしたほうがいいかなと思って、色々試してようやく使えるようになりました。あと、面倒なのでdocker-compose
は使用してません。
今回使用しているのはMQTT
のオープンソース実装であるMosquitto
を使っています。Windowsバイナリもあるので、正直それを使ったほうが楽です😁コンテナにしているので他の処理系でもほぼ同じように使えるのがいい点でしょうか。コンテナを使ってというのであればDocker
でなくてもWSL
を使用するという手ももちろんありかなと思います。
このMosquitto
のDockerイメージは以下にあります。サイズは11MByte程度。このサイズ感ならDocker
でいいですよね。
こちらのページのドキュメントにも導入の方法は書いてありますが、ちょっとだけ注意点はありますので、それも含めてメモとしていきます。
設定ファイルの準備
Mosquitto
はコンテナのイメージを持ってきて起動するだけではうまくいきません。Mosquitto
の設定ファイルであるmosquitto.conf
ファイルを作成する必要があります。設定ファイルの内容については先程のコンテナ説明のページに記載されています。
設定ファイルの内容をMosquitto
起動時に読み込まれるようにすればよいのですが、コンテナ起動時に設定ファイルがないとうまく起動できません。そこで今回は以前も使用したローカルファイルシステムのマウント機能(-v
オプション)を使用して、Windows側のファイルシステムにMosquitto
の設定ファイルを配置して、起動時に読み込まれるようにします。
注意点の1点目はWindowsのパス表記の方法です。特にドライブレターを含んだパスの表記は癖があるので注意しましょう。
参考
今回は設定ファイルをわかりやすくCドライブのルートにmosquitto
というフォルダを作成し、マウントしていきます。パスの表記としてはルート部分(ドライブレターがCドライブであれば)が/c/
となっているのがポイントになります(Windowsのみのtips😅)
作成したフォルダ
設定ファイルの内容
mosquitto.confの内容(コピー&ペースト用)
persistence true persistence_location /mosquitto/data/ log_dest file /mosquitto/log/mosquitto.log
これで設定ファイルの準備ができました。あとはこの設定ファイルを参照するようにコンテナを作成します。
コンテナ構築・起動
実行方法もコンテナのページにかかれていますが、かなり親切にかかれています。
自分がドキュメントから変更した点は先ほどのマウント機能で(-v
オプション)ドライブレターを含んだパスにしている点とホストネームの部分になります。起動コマンドに含まれているport番号1883と9001はホスト側からも共有できるようになっているので、Windows版のMosquitto
をローカルホストにインストールした場合とほぼ同じように使用できるようになるかと思うのですが、実際は別マシン扱いになるので注意が必要です(後述します)。
以下の様に起動するとMosquitto
コンテナが起動します。ホスト名はmymosquitto
としていますが、この名前はお好きなものに変更してください。
コンテナ構築・起動用のコマンド
PS > docker run -it -p 1883:1883 -p 9001:9001 -v /c/mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log --name mymosquitto eclipse-mosquitto
コンテナ構築・起動が無事に行われたら、あとは通信のテストを行っていきます。
MQTTの実行テスト
コンテナが起動すると自動でMosquitto
のbroker(実行プログラム名はmosuquitto
)が自動的に起動しています。コンテナ側のpsコマンドを使用するとプロセスの起動状態を確認することができます。ちなみに起動は以下の様にしても行うことができます。
$ mosquitto -v
ブローカの起動が確認できたら、CLIからMosquitto
のsubscriber(実行プログラム名はmosquitto_sub
)を起動します。テスト用のTopicはtest/topic
としています。後述のpublisher側のTopicとsubscriberのTopicが合致すると、subscriber側にメッセージが受信します。
mosquitto subscriberの起動
$ mosquitto‗sub -t test/topic
あとは別途コンソールを起動し、Mosquitto
のpublisher(実行プログラム名はmosquitto_pub
)を起動して、メッセージを送信すればsubscriber側でメッセージが受信されます。
mosquitto publisherの起動
$ mosquitto_pub -t test/topic -m ”hello world!”
登録されたTopicのsubscriberが複数存在していれば、brokerがsubscriber側にメッセージを送信してくれます。
今回は同一ホストでsubscriberとpublisherが起動していたので、起動時オプションにホストを指定はしていませんが、オプションスイッチで-h
を指定することで起動しているホストも指定できます。Mosquitto
コンテナ側はDockerホストとポートの転送設定も行っているので、Windows側のMQTT
クライアントからも同様に通信を行うことが可能です。
Windows版のmosquittoからの通信テスト
では、本当にDockerホストとなっているWindows側から通信が確認できるかを試してみます。注意しないとハマります。
Windows版のMosquitto
があるのでそれをWindowsにインストールして動作を確認してみます。
以下からWindows版のMosquitto
をダウンロードして、インストールを行っていきます。
ダウンロードし、ファイルを実行するとmosquittoコマンド群
のインストールが行われます。
インストール① 【Next >】ボタンをクリック
インストール② 【Next >】ボタンをクリック
インストール③ 【Install】ボタンをクリック
インストール④ 【Finish】ボタンをクリック
注意点としてはmosquitto
(broker)が自動起動されている点です(サービス化設定しないと立上がらないのかなと思ったのですが、起動はしているようです)。そのままではDocker側のmosquitto
と重複して実行され通信ができません(Docker側に通信が届きません)。もしこの方法で通信を試すのであれば、mosquitto
(broker)をPowerShell
のGet-Process
コマンド(エリアスはps
)でプロセスIDの確認を行った後、Stop-Process
コマンド(エリアスはkill
)で終了させてから試すようにしてください。Windows側でログを確認してもWindows側のsubscriberが起動していなければ、表示も行われないのでどこがおかしいかわかりにくいので、原因を調べるのがかなり大変でした。
PowerShellのAlias機能使用した停止する例
PS > ps -Name mosquitto # mosquittoプロセスのIDが4666であった場合 PS > kill -ID 4666
Windowsプロセスのmosquitto
(broker)を終了させれば、Docker
側のmosquitto
(broker)と通信ができるのですが、まだだめです。Docker
側とホスト側は別ホスト扱いになっているため、通信が制限されてしまいます。Mosquitto
ではデフォルトでは同一ホスト以外のbrokerとの通信しかできないようになっています。
そのため、ほかのホストからのMQTT
通信を行う場合には設定ファイルであるmosquitto.conf
以下のように編集していきます。最後の2行がはホストとの通信に使用する設定になります。
mosquitto.confの変更内容(コピー&ペースト用)
persistence true persistence_location /mosquitto/data/ log_dest file /mosquitto/log/mosquitto.log listener 1883 allow_anonymous true
念のため、先ほどのコンテナを削除し、再度読み込まれるようにコンテナを構築・起動を行います。
(再掲)コンテナ構築・起動用のコマンド
PS > docker run -it -p 1883:1883 -p 9001:9001 -v /c/mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log --name mymosquitto eclipse-mosquitto
このコンテナを起動し、Windows側のmosquitto_pub
(publisher)でメッセージを送信すると、Dockerコンテナ側のmosquitto_sub
(subscriber)にデータが受信されています。Dockerコンテナからも通信できているのがわかります。
おわりに
MQTT
のオープンソースの実装であるMosquitto
をDockerコンテナ上で動作させることができるようになりました。これで、IoT機器などのデバイスとの通信もできるようになりました。RaspberryPi
にもMosquitto
があり利用できますし、pythonからでもモジュールを使用することでプログラム内からMQTT
を使用できるかと思います。