MQTT
センサや小型機器のための、小さな発行/購読メッセージ。
CONNECT
クライアントが最初に挨拶するパケットです。長さ付きの文字列と、詰め込まれたフラグのバイトに注目してください。
フレーム全体
10 10 00 04 4D 51 54 54 04 02 00 3C 00 04 64 65 6D 6F: 実用最小の CONNECT です。固定ヘッダ 2 バイト、可変ヘッダ 10 バイト、ペイロード 6 バイト。
| フィールド | 位置 | 例の値 | 意味 |
|---|---|---|---|
| パケット種別 | 0 バイト目の bits 7–4 | 1 = CONNECT | 上位 4 ビットがパケットの種類です。1 CONNECT、2 CONNACK、3 PUBLISH、4 PUBACK、8 SUBSCRIBE、9 SUBACK、12 PINGREQ、14 DISCONNECT。 |
| フラグ | 0 バイト目の bits 3–0 | 0 | 下位 4 ビットは種別ごとに意味が変わります。CONNECT では 0000 が必須です。 |
| 残りの長さ | 1 バイト目 | 16 bytes follow | このフィールドより後ろのバイト数: 16。可変長整数で、1 バイトあたり 7 ビット、最上位ビットが「次のバイトが続く」の印です。127 までは 1 バイト、256 MB のパケットで 4 バイトになります。 |
| プロトコル名の長さ | 2–3 バイト目 | 4 | MQTT の文字列は、2 バイトの長さのあとに UTF-8 のバイトが続く形です。 |
| プロトコル名 | 4–7 バイト目 | MQTT | 文字列 'MQTT' そのものです。ブローカーはこれで MQTT 以外の通信を早く弾けます。 |
| プロトコルレベル | 8 バイト目 | 4 = v3.1.1 | 4 = MQTT 3.1.1、5 = MQTT 5.0。 |
| 接続フラグ | 9 バイト目 | 0x02 = Clean Session | ペイロードにどの任意要素が含まれるか、セッションをどう扱うかを示します。ここでは Clean Session だけが立っています。 |
| キープアライブ | 10–11 バイト目 | 60 s | クライアントが黙っていてよい秒数です。ブローカーはこの 1.5 倍の時間何も聞こえなければ接続を切ります。クライアントは PINGREQ を送ってその範囲に収めます。 |
| クライアント ID の長さ | 12–13 バイト目 | 4 | クライアント識別子の文字列の長さ。 |
| クライアント ID | 14–17 バイト目 | demo | ブローカーがこのクライアントを識別する名前です。一意である必要があり、同じ ID で 2 回接続すると、先の接続が追い出されます。 |
概要
MQTT は TCP の上で動く軽量な発行/購読プロトコルです。機器はブローカーに接続し、名前付きのトピックへメッセージを発行し、トピックのパターンを購読します。ブローカーがその間を取り持ちます。パケットは 2 バイトの固定ヘッダを持ち、全体でもわずか数バイトのことがよくあります。
3 段階の QoS が、帯域と確実さを引き換えにします。0 は投げっぱなし、1 は少なくとも 1 回、2 はちょうど 1 回。
基本情報
- トランスポート
- TCP 1883 (8883 with TLS)
- モデル
- publish / subscribe via broker
- 固定ヘッダ
- 2〜5 バイト
- QoS
- 0, 1, 2
- キープアライブ
- PINGREQ / PINGRESP
- 規格
- OASIS MQTT 3.1.1 / 5.0
PUBLISH
センサの測定値をトピックへ送ります。4 バイトのペイロードに 15 バイトのオーバーヘッドです。
フレーム全体
32 11 00 09 68 6F 6D 65 2F 74 65 6D 70 00 0A 32 31 2E 35: home/temp トピックへの 4 バイトの測定値です。オーバーヘッドは 15 バイトだけで、遅い回線上の小さなセンサに MQTT が向く理由です。
| フィールド | 位置 | 例の値 | 意味 |
|---|---|---|---|
| パケット種別 | 0 バイト目の bits 7–4 | 3 = PUBLISH | 3 = PUBLISH。トピックの購読者へメッセージを運びます。 |
| フラグ | 0 バイト目の bits 3–0 | 0010 = QoS 1 | PUBLISH では、フラグが配信オプションを運びます。ここでは QoS = 1(少なくとも 1 回)。 |
| 残りの長さ | 1 バイト目 | 17 | 17 バイトが続きます。2(トピック長)+ 9(トピック)+ 2(パケット ID)+ 4(ペイロード)。 |
| トピックの長さ | 2–3 バイト目 | 9 | トピック名の長さ。 |
| トピック | 4–12 バイト目 | home/temp | '/' で階層を区切る名前です。購読側は home/+ や home/# のようなワイルドカードを使えます。メッセージはアドレスではなくトピックで配送されます。 |
| パケット ID | 13–14 バイト目 | 10 | QoS が 0 より大きいときだけ存在します。PUBACK がこの値を返すので、送信側はどのメッセージが受理されたか分かります。 |
| ペイロード | 15–18 バイト目 | 21.5 | メッセージ本体です。MQTT は形式を問いません。ここではテキスト '21.5' ですが、JSON でも生のバイナリでも構いません。 |
QoS 1 での発行
購読から、配信と確認応答まで。真ん中にブローカーがいます。
やり取りの全体
発行側と購読側は直接話しません。ブローカーがトピックで配送します。QoS のレベルが、各メッセージを守る確認応答の数を決めます。
1アプリが購読する
購読側が、欲しいトピックをブローカーに伝えます。home/# は home/ 以下のすべてにあたるワイルドカードです。
2ブローカーが確認
ブローカーが購読と、使用する QoS を確認します。
3センサが発行する
センサは誰が聞いているか知りません。測定値をトピックへ、QoS 1・パケット ID 10 で送るだけです。
4ブローカーが配る
ブローカーが、パターンがトピックに一致するすべての購読者へ転送します。
5アプリが確認応答
購読側の PUBACK が配信完了をブローカーに伝えます。これがなければブローカーは再送します。
6センサに受領が届く
ブローカーがセンサのパケット ID 10 を確認応答します。メッセージは受理されました。これが届かなければ、センサは DUP を立てて再送します。QoS 1 が「少なくとも 1 回」である理由です。
使われる場面
- IoT センサやスマートホーム機器(Home Assistant、Zigbee2MQTT)
- 不安定な回線上の車両や産業機器のテレメトリ
- 初期の Facebook Messenger がモバイルのプッシュ配信に使っていました
つまずきやすい点
- 同じクライアント ID の 2 台は、互いを追い出し合うループになります。機器ごとに一意の ID を付けてください。
- Retain されたメッセージは、そのトピックへ空の Retain ペイロードを発行するまで、ブローカーに残り続けます。
- トピックは大文字小文字を区別し、先頭の '/' は、空の別の第 1 階層を作ります。
出典・規格
- OASIS MQTT Version 3.1.1
- OASIS MQTT Version 5.0