MQTT(Message Queueing Telemetry Transport)って何?

メモ:  Category:blog

IoT(Internet of Things) という言葉、出初めのころは新しい言葉がいつまで続くのかと思っていたのですが、自分が思っていたよりも目にすることが多くなってきました。自分の周りの環境で、どんな情報を扱うと有益なのかイメージできませんが、少しずつ情報を仕入れていきたいと思っています。

ふわふわと、 IoT についてさまよい今日たどり着いたのが MQTT という4文字です。

MQTT とは、 Message Queuing Telemetry Transport の略で TCP/IP ネットワークで利用可能な通信プロトコルの一種です。シンプルで軽量なところがセールスポイント?となっており、機械同士が通信を介して情報をやり取りする M2M (Machine-to-Machine) や、家電や自動車など多種多様な「モノ」がインターネットを介して、情報をやり取りする IoT (Internet of Things) 等に適したプロトコルと言われています。

ここまで書いてなんなんですが、ソフトバンクがIPアドレス無しで通信する IoT 向け NIDD (Non-IP Data Delivery) なるもの試験サービスを開始するというニュースも出ていたので、 IoT はどこに向かっていくのでしょうか...と思ってもいます。(世界初、NB-IoT向けNIDD技術を使用した商用環境での試験サービスを開始

Message Queueing Telemetry Transport

MQTT は、ブローカーベースの軽量なパブリッシュ/サブスクライブ型メッセージプロトコルだそうです。この説明では、3つの機能が登場するので順に確認していきたいと思います。

全体的なイメージは、次の通りとなります。

MQTTのイメージ

パブリッシュ(Publisher)

登場順とは違いますが、まずメッセージを送信する側をパブリッシャーと言います。パブリッシャーは、フォーマットに従ってメッセージをブローカーへ送信(パブリッシュ)します。

サブスクライブ(Subscriber)

メッセージを受信する側をサブスクライバーと言います。パブリッシャーが送信したメッセージをブローカーを経由して受信します。

ブローカー(Broker)

ブローカーは、パブリッシャーからサブスクライバーへメッセージを橋渡しする機能になります。

MQTTの仕組み

次のコードは、 26.5 というメッセージを送信するパブリッシャーの簡単な例です。 paho-mqtt パッケージを使用した Python のプログラムになります。

サブスクライバー(受信側)は、この Topic で必要なメッセージを受信します。

from time import sleep
import paho.mqtt.client as mqtt

TOPIC = 'office/Oregon/warehouse/temp'
HOST = '127.0.0.1'
PORT = 1883
KEEP_ALIVE = 60

# インスタンス作成
client = mqtt.Client(protocol=mqtt.MQTTv311)

client.connect(HOST, port=PORT, keepalive=KEEP_ALIVE)

for i in range(3):
    client.publish(TOPIC, '26.5')
    sleep(0.2)

client.disconnect()

Topic

MQTT では、メッセージを識別するために / で区切られた Topic という文字列を使用します。 Topic は、/ 区切りによって階層構造を表現することができます。例えば、次のような 3 種類の Topic があるとします。

office/Oregon/1441 Building
office/Oragon/warehouse
office/Idaho/warehouse 

この Topic の階層構造は、次の図のようになります。

Topicの階層構造

また、サブスクライブする時の Topic 指定では、ワイルドカードを使うことができ、1 つの指定で複数の Topic を同時に指定することができます。ワイルカードには、シングルレベル・ワイルドカードとマルチレベル・ワイルドカードがあり、それぞれ、+ 記号と # 記号を使って表現します。

例えば、シングルレベル・ワイルドカード(+)を次のように指定したとします。

office/+/warehouse

この指定の場合、+ 記号を指定した階層のみにワイルドカードが指定され、それ以降の階層が一致したものがサブスクライブ対象となります。

office/Oragon/warehouse
office/Idaho/warehouse 

マルチレベル・ワイルドカード(#)は、指定した階層以降にあるすべてが対象となります。

office/#

データの扱いが少し見えてきたので、サブスクライバーについて見ていきます。パブリッシャーが送ったメッセージを受け取るサブスクライバーの簡単な例が次のコードとなります。

import paho.mqtt.client as mqtt

TOPIC = 'office/Oregon/1F/temp'
HOST = '127.0.0.1'
PORT = 1883
KEEP_ALIVE = 60

def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))

    client.subscribe(TOPIC)

def on_message(client, userdata, msg):
    print(msg.topic + ' ' + str(msg.payload))

if __name__ == '__main__':

    client = mqtt.Client(protocol=mqtt.MQTTv311)

    client.on_connect = on_connect
    client.on_message = on_message

    client.connect(HOST, port=PORT, keepalive=KEEP_ALIVE)

    # メッセージを待ち受ける状態にする
    client.loop_forever()

ブローカーについては、 AWS IoT や CloudMQTT 等を使用したり自前で Mosquitto 等を用意したりするようです。

bluenote by BBB