朝から昼寝

整理しておきたいIT関連の小ネタ

Windows上で手軽にMQTTブローカーを立ち上げる(Mosquitto)

概要

IoT機器等で使用されるPub/Sub型プロトコル、MQTT。構成上必要となるMQTTブローカーとして、Mosquittoなどがあります。
本記事は、Windows版Mosquittoを用いてMQTTブローカーを立ち上げる方法について記載します。環境は、Mosquitto 2.0.14をWindows 10上で動作させたものです。おそらくLinux版でも大きな違いは無いと思います。

本記事の目的

  • MQTTブローカーとしてMosquittoをインストールし、動作させる。
  • 簡単な構成変更や、WebSocket設定、デバッグログ設定の方法を把握する。

目次

基本

インストール

mosquitto.orgからWindowsインストーラをダウンロードします。今回はmosquitto-2.0.14-install-windows-x64.exeを使用しました。
基本的にデフォルトのままインストールウィザードを実行するだけでインストール完了です。

インストール直後の動作確認

インストールが終わったら、ひとまず簡単に動作確認をします。

コマンドによるMQTTブローカー起動

コマンドプロンプトのウィンドウを3つ使用します。

1つ目のコマンドプロンプト(ブローカー用)で以下のコマンドを実行します。

>"c:\Program Files\mosquitto\mosquitto.exe" -v

MQTTブローカーのサービスがlocalhostのインタフェースでlistenされます(詳細は後述)。

次に、2つ目のコマンドプロンプト(Subscribe用)で以下のコマンドを実行します。

>"c:\Program Files\mosquitto\mosquitto_sub.exe" -h localhost -t "test/Topic1"

localhostのインタフェース上で起動したMQTTブローカーに対し、"test/Topic1"というトピックのSubscribeを開始します。

さらに、3つ目のコマンドプロンプト(Publish用)で以下のコマンドを実行します。

>"c:\Program Files\mosquitto\mosquitto_pub.exe" -h localhost -t "test/Topic1" -m "test desu."

localhostのインタフェース上で起動したMQTTブローカーに対し、"test/Topic1"というトピック宛に"test desu."というメッセージをPublishします。
ここで、2つ目のコマンドプロンプト(Subscribe用)の画面に、"test desu."というメッセージが表示されたらOKです。MQTTブローカーの起動と、PublishとSubscribeの簡易的な動作確認ができました。

サービスによるMQTTブローカー起動

Mosquittoをインストールすると、Windows上に"Mosquitto Broker"というサービスが登録されます。このサービスを起動させておくと、先ほどの"1つ目のコマンドプロンプト(ブローカー用)"でmosquitto.exe" -vを実行したときと同じようにMQTTブローカーが起動した状態になります。
あとは、先ほどと同様に"2つ目のコマンドプロンプト(Subscribe用)"でmosquitto_sub.exeコマンドと、"3つ目のコマンドプロンプト(Publish用)"でmosquitto_pub.exeコマンドを実行し、PublishとSubscribeの簡易的な動作確認が可能です。

本記事の以降の説明は、基本的にMosquitto Brokerサービスを使用した環境に関するものです。

詳細

設定変更

listenするインタフェースや使用するプロトコル等の変更

インストール直後の状態でMosquittoを起動すると、localhostのインタフェースでのみMQTTのサービスをlistenする動作になるようです(local only mode)。

mosquitto.conf内の説明文から少し読み取りづらいですが、このlocal only modeはallow_anonymousの箇所に説明があり、listenerを設定しない場合はlocalhostからのみ認証無し(allow_anonymousが"true"相当)で接続可能な旨の記載があります。

以下のように設定する例を記載します。ポート番号は任意です。

  • すべてのIPインタフェース(IPv4IPv6両方)で、MQTTサービスを起動(1883/tcp)
  • すべてのIPインタフェース(IPv4のみ)で、MQTT on WebSocketサービスを起動(9090/tcp)

MQTT on WebSocketサービスの設定は行わなくても、通常のMQTTを使用することが可能です。詳細については本記事では省略しますが、WebSocket経由でMQTTを使用するためのものです。

管理者権限でテキストエディタを起動し、以下ファイルを開きます。
C:\Program Files\mosquitto\mosquitto.conf

以下の行を追加します。

listener 1883

listener 9090
protocol websockets
socket_domain ipv4

allow_anonymous true
  • 追加する内容は、confの該当設定の説明がある箇所への追記、あるいは、まとめて最終行への追記、どちらでも大丈夫です。
    • ただし、listener行は複数定義できるので、各行の記載順序について注意が必要です。
      listener行の"直後"に、そのlistener行で指定したポート番号(やIPアドレス)に対して適用したい内容のprotocol行やsocket_domain行をセットで記載する必要性があります。"直後"というのは、次のlistener行の前という意味です。
  • listener 1883:すべてのIPインタフェース(IPv4IPv6両方)で、MQTTサービスを起動(1883/tcp)する設定です。
  • listener 9090:MQTT on WebSocketサービスを起動(9090/tcp)する設定です。IPアドレスの指定を省略しているので、すべてのIPインタフェースでlistenする動作となりますが、IPv4インタフェースでのみ動作させるよう後述のsocket_domain ipv4を加えてあります。WebSocketを使用しない場合は、この設定は不要です(protocol websocketssocket_domain ipv4も)。
    • protocol websockets:通常のMQTTでなく、WebSocketを使用する設定です。protocol行を省略すると通常のMQTTが動作します。
    • socket_domain ipv4:このサービスをIPv4でのみlistenする指定です。mosquitto.conf内の説明文によると、WebSocketはライブラリの都合で、IPv6インタフェースでのみListenしようとするようなので、IPv4インタフェースを使用したい場合はこの設定が必須です。socket_domain行の省略時は、すべてのIPインタフェース(IPv4,IPv6)でlistenします。
  • allow_anonymous true:認証無しでの接続を許可する設定です。本記事の説明では認証を行わない構成としています。※listener行を定義すると、デフォルトのallow_anonymous falseが有効になります。
  • その後:必要に応じWindowsファイアウォールで1883/tcpと9090/tcp宛の通信を許可しましょう。環境に応じ、許可する接続元IPアドレスは絞っておきましょう。
    また、他にも設定可能な項目はたくさんありますが、詳細はマニュアル等を参照願います。本記事では通信のTLS対応は行っていません。

上記設定により、意図通りにlistenされます。

> netstat -an | findstr 1883
            TCP         0.0.0.0:1883           0.0.0.0:0              LISTENING
            TCP         [::]:1883              [::]:0                 LISTENING
> netstat -an | findstr 9090
            TCP         0.0.0.0:9090           0.0.0.0:0              LISTENING

サービスの自動起動設定

OS起動時にサービスを自動起動させたい場合は、Windowsのサービスの管理画面(コンピューターの管理)で、Mosquitto Brokerサービスのスタートアップの種類を"自動"にしておきます。

デバッグログの確認

デバッグログの有効化

Mosquitto動作時の詳細ログを記録したい場合には、mosquitto.confに以下の行を反映(追記)し、Mosquitto Brokerサービスを再起動します。

log_dest file C:\xxx\mosquitto.log
log_type debug
connection_messages true
log_timestamp true
log_timestamp_format %Y-%m-%dT%H:%M:%S
  • log_dest:ログファイルのパスを指定します。
  • log_type:ログレベルを指定します。"debug, error, warning, notice, information, none, subscribe, unsubscribe, websockets, all"を指定可能のようです。複数のlog_type行を設定できるようです("debug"には全てのログが含まれると思いますが詳細は未確認です)。
  • connection_messages:MQTTクライアントの接続、切断をログに記録するかどうかを指定します。
  • log_timestamplog_timestamp_format:ログの各行にタイムスタンプを記録するかどうか、またそのフォーマットを指定します。

上記設定により、log_destで指定したパスにログファイルが作成されます。debugを指定するとログの出力量が増えるため、通信量が多い環境ではログファイルの肥大化に注意が必要です。

デバッグログの出力例

以下は、log_typeに"debug"を指定した場合のログ出力例です。

2022-XX-XXT12:34:55: Sending CONNACK to M5Stack (0, 0)
2022-XX-XXT12:34:55: Sending CONNACK to auto-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx (0, 0)
2022-XX-XXT12:34:55: Sending CONNACK to Browser-xx (0, 0)

2022-XX-XXT12:34:56: Received SUBSCRIBE from auto-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx
2022-XX-XXT12:34:56:    test/Topic1 (QoS 0)
2022-XX-XXT12:34:56: Sending SUBACK to auto-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx

2022-XX-XXT12:34:57: Received SUBSCRIBE from Browser-xx
2022-XX-XXT12:34:57:    test/Topic1 (QoS 0)
2022-XX-XXT12:34:57: Sending SUBACK to Browser-xx

2022-XX-XXT12:34:58: Received PUBLISH from M5Stack (d0, q0, r0, m0, 'test/Topic1', ... (73 bytes))

2022-XX-XXT12:34:58: Sending PUBLISH to auto-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx(d0, q0, r0, m0, 'test/Topic1', ... (73 bytes))
2022-XX-XXT12:34:58: Sending PUBLISH to Browser-xx (d0, q0, r0, m0, 'test/Topic1', ... (73 bytes))

上記のログは、以下動作時の記録です。

  • 各MQTTクライアントから接続があった(CONNACK)。
    それぞれのクライアントID(thingId的なもの)は"M5Stack"、"auto-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"、"Browser-xx"。
    この例では、"auto-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"は前述のmosquitto_sub.exeコマンド実行時のMQTT接続、"Browser-xx"は、JavaScriptのMQTTライブラリを使用しWebSocket経由でのMQTT接続。
  • 各MQTTクライアントから、トピック"test/Topic1"に対しSubscribe要求があった(SUBSCRIBE、SUBACK)。
  • MQTTクライアント"M5Stack "から、トピック"test/Topic1"に対しPublishされた(Received PUBLISH)。
  • Publishされたトピック"test/Topic1"に対するメッセージを、SubscribeしているMQTTクライアント"auto-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"、"Browser-xx"に送信した(Sending PUBLISH)。

参考URL等