MQTT
IoT機器向けの軽量なメッセージングプロトコル。TCPの上で動き、送信者(パブリッシャ)と受信者(サブスクライバ)が、ブローカーと呼ばれるサーバを介してメッセージをやり取りする(パブリッシュ/サブスクライブ型)。
イマシルちゃんの解説
MQTTは、温度センサなどのIoT機器で使われる軽量なメッセージ通信のプロトコルだよ。
メッセージを仲介するブローカーというサーバを利用するんだ。
メッセージには「部屋1の温度」などの分類名であるトピックを付けるよ。
受信者のサブスクライバは、受け取りたいトピックをブローカーに登録して購読するの。
送信者のパブリッシャは、測定値にトピックを付けてブローカーへ送るよ。
ブローカーが、そのトピックを購読しているサブスクライバへ測定値を配信するんだ。
このような送り方をパブリッシュ/サブスクライブ型というよ。
センサは受信者一台ずつの宛先を管理しなくていいから、スマホや記録用サーバをあとから追加しやすいんだ。
この解説はわかりやすかったですか?
より深い解説
定義
MQTT(Message Queuing Telemetry Transport)は、OASISで標準化された、パブリッシュ/サブスクライブ型のメッセージングプロトコルである。ヘッダーが最小2バイトと小さく、処理能力やバッテリーの限られたIoT機器や、不安定な回線での利用を想定して設計されている。通常はTCPの1883番ポート(TLSを使う場合は8883番)を使う。
パブリッシュ/サブスクライブ型
| 役割 | 内容 |
|---|---|
| パブリッシャ | メッセージにトピック(例:factory/line1/temperature)を付けてブローカーに送る |
| ブローカー | メッセージを受け取り、そのトピックを購読しているサブスクライバに配る |
| サブスクライバ | 関心のあるトピックをブローカーに登録(購読)し、メッセージを受け取る |
送信者と受信者が互いを直接知る必要がなく、1対多の配信や、機器の追加・削除がしやすい。
一つのクライアントが発行と購読を両方行ってもよい。例えば温度センサーは測定値を発行しながら、測定間隔の変更指示を購読できる。機器からブローカーへ確立したTCP接続は双方向に使えるため、指示を受け取るたびにブローカーから機器へ新しい接続を開始する必要はない。NATやファイアウォールを越える構成では、この既存接続とその通信状態を維持する。
接続、購読、配信のパケット
MQTT 3.1.1では次の制御パケットを使い分ける。接続を受け付けたことと、購読を受け付けたことは別の応答である。
| 制御パケット | 送信する側と役割 |
|---|---|
| CONNECT | クライアントがMQTT接続を要求する。クライアントIDや接続条件を渡す |
| CONNACK | ブローカーが接続要求の結果を返す |
| SUBSCRIBE | クライアントが受け取りたいトピックフィルタと、その購読で受信したい最大QoSを登録する |
| SUBACK | ブローカーが購読要求の結果を返す。受理したQoSまたは失敗を知らせる |
| PUBLISH | アプリケーションのデータを運ぶ。発行者からブローカーへも、ブローカーから購読者へも使う |
| PUBACK | QoS 1のデータ受信を確認する |
| PUBREC | QoS 2のデータを受信したことを返す |
| PUBREL | QoS 2で受信通知を受けた送信側が、受信側へ次の処理を進めるよう知らせる |
| PUBCOMP | QoS 2の受信処理の完了を知らせる |
ブローカーは、配信データのトピック名と登録済みのトピックフィルタを照合して宛先を選ぶ。例えば plant/+/temperature は中間の1階層だけを任意とする。末尾の # は複数階層を含めて照合する。ワイルドカードは購読条件に使い、発行するデータのトピック名には使わない。
ヘッダーとデータの位置
全制御パケットは固定ヘッダーを持ち、種類やフラグ、残りの長さを表す。可変ヘッダーとペイロードが続くかどうか、その中身はパケットの種類による。すべての種類に三つの部分が必ずそろうわけではない。
| パケット | 可変ヘッダーとペイロードの主な内容 |
|---|---|
| CONNECT | 接続条件を可変ヘッダーに、クライアントIDなどをペイロードに置く |
| PUBLISH | トピック名を可変ヘッダーに、実際の測定値などをペイロードに置く。QoS 1・2ではパケット識別子も持つ |
| SUBSCRIBE | パケット識別子を可変ヘッダーに、購読条件と要求QoSをペイロードに置く |
パケット識別子は、応答を元の要求や配信へ対応付けるための16ビット値である。QoS 0のデータ配信には含めない。長さが0のペイロードを持つデータ配信も可能であり、ペイロードがないことだけで不正とは判定できない。
QoS(配信の保証レベル)
| QoS | 意味 | 内容 |
|---|---|---|
| 0 | At most once | 最大1回。MQTTの確認応答を使わず、届かないこともある |
| 1 | At least once | 少なくとも1回。受信確認と未完了の配信状態を管理するため、再配信で重複する可能性がある |
| 2 | Exactly once | ちょうど1回。4段階のやり取りと状態管理で、同じ配信を重複して受け渡さない |
QoS 2のやり取りは次の順となる。途中のパケットが再配信されても、受信側はパケット識別子と保存した状態から既存の処理を判別する。
QoSは発行者からブローカー、ブローカーから購読者という各配送区間で適用される。ブローカーからの配信QoSは、受信したメッセージのQoSと、購読時に受理された最大QoSの両方を上限として決まる。発行時にQoS 2を指定しても、QoS 0で購読する相手まで必ずQoS 2になるわけではない。また、業務処理の完了やデータベースへの保存を直接保証する機能ではない。
CoAPとの比較
| MQTT | CoAP | |
|---|---|---|
| トランスポート | TCP | UDP |
| 通信モデル | パブリッシュ/サブスクライブ(ブローカー経由) | リクエスト/レスポンス(HTTPに似たRESTの方式) |
| メッセージの形式 | バイナリ | バイナリ(固定ヘッダー4バイト) |
| 信頼性の確保 | TCPと、MQTTのQoS | 確認応答付きのメッセージ(CON)で再送 |
| 向いている場面 | 多数の機器からデータを集める、通知を配る | 小電力の機器を直接操作する、制約の厳しいネットワーク |
その他の機能
| 機能 | 内容 |
|---|---|
| Retain | トピックの最後のメッセージをブローカーが保持し、新しいサブスクライバにすぐ送る |
| Will(遺言) | 機器が不意に切断されたとき、あらかじめ登録したメッセージをブローカーが配信する |
| Keep Alive | 定期的に通信して、接続が生きていることを確認する |
参考資料
- OASIS MQTT Version 3.1.1の第2章、第3章、第4章にパケット構造、各パケットの役割、配送の手順が定められている。