MQTTについて詳しく知る

はじめに

ここでは、「MQTT」というプロトコルについて解説しています。

MQTTは1999年にIBM社とEurotech社のメンバーにより考案されたプロトコルで、2014年8月現在における最新のバージョンはMQTT3.1.1です。現在、コンピュータと通信に関する標準化団体であるOASISによって、MQTTの標準化が進められています。

MQTTの特長

MQTTとは、M2MやIoTの実現に適したシンプルで軽量なプロトコルです。

MQTTはM2M (Machine-to-Machine)、すなわち機械と機械が通信ネットワークを介してお互いに情報をやり取りすることや、IoT (Internet of Things)、すなわち家電や自動車など多種多様な「モノ」がインターネットにつながり、お互いに情報をやり取りすることを実現するのに適したプロトコルです。MQTTでは、あらゆる「マシン」や「モノ」に取り付けた、低帯域でメモリー容量の小さなセンサーやデバイスなどから情報を送ることを想定しています。

MQTTは、一方向、1対1の通信のみでなく、双方向、1対多の通信が可能です。また、MQTTのプロトコルヘッダーは最小2バイトと小さく、その軽量さから、特にバッテリーの消費を抑えたいモバイル向けの通信に適していることが特長の一つです。また同期処理が必要となるHTTPと比較して、処理速度に優れており、とくにリアルタイムでのプッシュ型のメッセージ配信においては、転送量を効果的に低く抑えることができます。

MQTTは、TCP/IPプロトコルの上で動作する、パブリッシュ/サブスクライブ型のモデルを採用しています。

パブリッシュ/サブスクライブ型のモデルでは、メッセージを送信する側をパブリッシャー、メッセージを受信する側をサブスクライバーといいます。実際にMQTTを利用してメッセージのやり取りを行うには、パブリッシャーとサブスクライバーとの間に、メッセージを仲介するMQTTサーバーを用意する必要があります。

パブリッシャーは、サブスクライバーを意識することなく、サーバーにメッセージの送信ができる一方で、サーバーは、それらのメッセージを一旦預かり、管理し、適切にサブスクライバーに配信する責任を持ちます。

パブリッシャーはトピックを指定してサーバーにメッセージを送信し、送信されたメッセージは、サーバーによってそのトピックに対してサブスクライブを申し込んでいたサブスクライバーに配信されます。

MQTTサーバー

  • パブリッシャーとサブスクライバーの間にはMQTTサーバーが存在し、メッセージの管理、配信を行います
  • パブリッシャーはトピックを指定して、メッセージをMQTTサーバに送信します
  • MQTTサーバは、サブスクライバーが指定しているトピックに該当するメッセージを配信します

※ トピックはパブリッシュされたメッセージをどのサブスクライバーが受信するべきかを決定するために使用されます

機能

下記に、MQTTの機能を細かく見ていきます。

トピック

サブスクライバーは、指定するトピックだけサブスクライブすることができます。

たとえば、あるデータセンターの温度と湿度についての情報を受信することを想定してみます。

/datacenter/abc/tokyo/floor/01/temperature
/datacenter/abc/tokyo/floor/01/humidity
/datacenter/abc/osaka/floor/01/temperature
/datacenter/abc/osaka/floor/01/humidity
/datacenter/xyz/tokyo/floor/05/temperature
/datacenter/xyz/tokyo/floor/05/humidity
/datacenter/xyz/nagoya/floor/12/temperature
/datacenter/xyz/nagoya/floor/12/humidity

トピックはこのように「/」で区切られた階層構造になっています。

サブスクライバー側では、サブスクライブしたいトピックを指定できます。この時完全一致ではなく、ワイルドカード(Wildcard)も指定できます。

/datacenter/abc/tokyo/floor/01/temperature

この場合は、完全一致、つまり「ABCデータセンターの、東京拠点にある、1階の温度」に関する情報だけがサブスクライブできます。

/datacenter/xyz/nagoya/#

「#」を使えば、前方一致という意味になります。つまりこの場合は、「XYZデータセンターの、名古屋拠点にある、すべての階の温度と湿度」に当てはまる情報がサブスクライブできます。

/datacenter/+/tokyo/floor/+/humidity

「+」を使えば、部分一致という意味になります。つまりこの場合は、「すべてのデータセンターの、東京拠点にある、すべての階の湿度」に当てはまる情報がサブスクライブできます。

「+」は「#」と組み合わせて使用することも可能です。

QoS

MQTTではメッセージごとに到達保証に関するQoS(サービスの品質)が指定でき、以下の3 種類から選択できます。

QoS0 : メッセージは最高 1 回 (At most once) 配信されます。
メッセージはTCP/IP ネットワークのベストエフォートに従って送信されるため、メッセージが送信先に届くかは保証されません。
QoS1 : メッセージは最低 1 回 (At least once) 配信されます。
メッセージが送信先に届くことが保証されますが、重複して届く可能性があります。
QoS2 : メッセージは正確に 1 回 (Exactly once) 配信されます。
メッセージが過不足なく 1 回のみ到着することが保証されます。たとえば、メッセージの重複や損失が許されない課金システムなどで利用できます。

Will

クライアントは最初にMQTTサーバーに接続した時にWillという情報を追加できます。ここでのWillは「遺言」の意味です。サーバーはそのクライアントとの通信が意図しない理由で切断された場合に、このWillで指定されたトピックとメッセージをサブスクライバ―に送信します。これにより、サブスクライバー側ではパブリッシュ側が「死んだ」ということを判断できます。なお、パブリッシュの死活判定は、一定間隔ごとに送られるpingに答えるかどうかで判断されます。この間隔も接続のたびに決められますので、このデバイスはバッテリーの消費が心配だからping間隔を長くしよう、といった設定ができます。

Retain

Retain機能とは、トピックごとに最後にパブリッシュされたメッセージをMQTTサーバーが保持しておき、新しいサブスクライバーにそのメッセージを渡す機能です。MQTTは前述のとおり、パブリッシュ/サブスクライブ型モデルです。そのため、パブリッシュされた時にサブスクライブしていたクライアントにしかメッセージは送信されません。たとえば1時間ごとに更新される情報を得ようとサブスクライブしても、最長1時間はなにも情報が得られないことになります。しかし、この場合でもRetain機能を使うとその時点での最新の情報が得られます。

セキュリティ

MQTTは、最初にサーバーに接続するときにユーザー名とパスワードを指定するようにできます。ただし、パスワード自体はクリアテキストで送られてくるのでTLS (Transport Layer Security) を通してセキュリティを構築することになっています。また、バージョン 3.1.1 からサブスクライバーを拒否する仕様は存在しますが、どのような理由で拒否するかは仕様では決まっていません。ただし、現在世の中に出ている一部のMQTTサーバーでは、ユーザー名ごとにパブリッシュ/サブスクライブそれぞれのアクセス管理をできる機能が実装されています。さきほどユーザー名とパスワードを指定すると書きましたが、この扱いについては実装依存です。通常の認証に加えて、LDAPやOAuthを使って認証をする、という実装も可能です。

参考・引用

MQTT Version 3.1.1
http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
MQTT V3.1 Protocol Specification
http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html
MQTT、IBM MessageSightのご紹介 - IBM MessageSight for Developersを使ってMQTTを体験する
http://www.ibm.com/developerworks/jp/websphere/library/connectivity/ms_mqttintro/

^

Niftycloud