Mosquitto(MQTT)を動かしてみた
MQTTとは
MQTT(MQ Telemetry Transport : MQはMessage Queuing?)というプロトコルで、TCP/IP層で動作するWebSocketっぽいもの(ザックリ)。詳しくはそこはかとなく書くよん。を見てもらった方が分かりやすいです。簡単に言えば、M2Mでの使用を考えた軽量なメッセージプロトコルという感じです。Mosquittoはブローカの実装で使用します。
2013年のカンファレンスでは、2011年当時の「Beluga」(現Facebook Messenger)に使われているという発表があったようです
MQTTのブローカとクライアントの動作確認の構成
今回下記のような構成でMQTTの動作確認を行いました。
Mosquittoにsub.pyで接続し、pub.pyによってpublishされるとsub.py側に出力されることを確認します。
Mosquitto(ブローカ)のインストール
パッケージからインストール
Ubuntuでは基本的にはパッケージインストールができるので
$ sudo apt-get install mosquitto
以上でインストールと起動まで完了します。停止・再起動はserviceコマンドで行えます。
ソースからコンパイルする場合
開発環境のインストール
$ sudo apt-get install gcc make g++ libssl-dev libc-ares-dev
Mosquittoのダウンロードページからソースを落として展開し、makeしてインストールします。
$ wget http://mosquitto.org/files/source/mosquitto-1.3.1.tar.gz $ tar -xvzf http://mosquitto.org/files/source/mosquitto-1.3.1.tar.gz $ cd mosquitto-1.3.1 $ make $ sudo make install
環境設定ファイルを設定します。
$ sudo cp /etc/mosquitto/mosquitto.conf.example /etc/mosquitto/mosquitto.conf
デフォルトでMQTTは1883ポートを使用します。必要に応じてサーバのポートを開放します。
起動します。
※引数なしの起動方法では前述のconfファイルは使われず、デフォルトで起動します。-cオプションでファイルを指定する必要がありますが、何も修正していなければ動作はデフォルトとなります。
$ mosquitto 1397719018: mosquitto version 1.3.1 (build date 2014-04-17 15:13:13+0900) starting 1397719018: Using default config. 1397719018: Opening ipv4 listen socket on port 1883. 1397719018: Opening ipv6 listen socket on port 1883.
この場合、サーバがIPv4/6両対応なので、ポートそれぞれでリッスンしている状態になります。
PahoクライアントでPub/Subを実行する
Pahoの下の方に各言語用のダウンロードリンクがありますので、そこからcloneしてきて利用するのがいいのと思います。今回はPythonクライアントのexampleを少し修正してsub.pyとpub.pyを作成しました。
paho MQTT pythonライブラリのインストール
$ sudo pip install paho-mqtt
sub.pyの実行
詳しい解説は後回しにしてまずは実行してみましょう。まずは待ち受けのsub.pyを実行しておきます。
コードはsub.pyにあります。
起動して、ブローカサーバに接続するとこのようなメッセージになります。
$ python sub.py rc: 0 Subscribed: 1 (0,)
ブローカサーバへの接続が失敗した場合こんなメッセージが出ます。
Traceback (most recent call last): File "sub.py", line 60, in <module> mqttc.connect("HOST", 1883, 60) File "/Library/Python/2.7/site-packages/paho/mqtt/client.py", line 588, in connect return self.reconnect() File "/Library/Python/2.7/site-packages/paho/mqtt/client.py", line 710, in reconnect self._sock = socket.create_connection((self._host, self._port), source_address=(self._bind_address, 0)) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 571, in create_connection raise err socket.error: [Errno 61] Connection refused
接続に成功していればブローカサーバ(Mosquitto)の方では以下のようなメッセージが表示されているはずです
1397719236: New connection from 2001:3e0:0:*:*:*:*on port 1883. 1397719236: New client connected from 2001:3e0:0:*:*:*:* as paho/E917914937EA634F0F (c1, k60).
一部"*"でマスクしています。
pub.pyの実行
次にpub.pyを実行して、メッセージを送信します。
コードはpub.pyにあります。
コンソールをもう一つ開いてpub.pyを実行すると直ぐに終了します。
$ python pub.py 1
sub.pyの出力の方を見てみると、1行メッセージが追加されていると思います。
rc: 0 Subscribed: 1 (0,) message 0 Hello MQTT!
pub.pyを実行することにより、subscribeしていたsub.pyの方にメッセージ送信が行われたことがわかります。
解説
sub.pyの方から見ていきます。(以下抜粋)
# メッセージを受信した時に呼ばれる。 def on_message(mqttc, obj, msg): print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) # 接続先のブローカを設定する mqttc.connect("HOST NAME", 1883, 60) # "message"というtopicをsubscribeする mqttc.subscribe("message", 0)
sub.pyは起動すると"message"というtopicが来るまで待機状態になります。pub.pyを実行して。メッセージを受信すると、topicとqosとpayloadを表示します。今の場合は
- topic : message
- qos: 0
- payload : Hello MQTT!
pub.pyの方はこれだけですね。
publish.single("message", "Hello MQTT!", hostname="HOST NAME")
"message"というtopicに"Hello MQTT!"を送信しています。qosは省略されていますが、デフォルトが0になっています。今回は簡単にするためにtopcを"message"としましたが、これを"$SYS/#"のようにワイルドカードで指定したり、"paho/test/single"のようにすることもできます。この指定の仕方はMQTTの仕様のようで、これを利用して各々のM2M機器がsubscribeする対象を設定できるようになっています。
まとめ
MQTTを実動作させるテストを行いました。MQTTの実装はLinuxやMacだけでなく、mbedやArduino、Androidなどにもありますし、様々な言語での実装もあります。またNode.jsでWebSocketと組み合わせてブラウザへの出力もできます(この辺は後日)僕はこのM2M用途としてのMQTTはよく知らなかったのですが、実際使用してみると結構いろいろなことが出来そうな気がします。プロトコルはシンプルだし、QoSの概念が導入されているのも面白い点です。