MQTTバージョン5の概要 2018年版

2018/12/11更新 COS(Candidate OASIS Standard)が11/16に発行されましたので、予想スケジュールをアップデートしました。

2019/3/10更新 3/8に、MQTTv5がついにOASIS標準になりました。

2019/3/22更新 MQTTv5の正式公開日が3/7となりました。

旧連載から約1年が経ち、MQTTバージョン5の標準化も完了が近づいて来ました。本稿では、最新の標準ドラフトに基づいて、MQTTバージョン5の要点解説をします。

なお、本稿は、v.3.1.1ベースでのMQTTプロトコルの知識がある方を対象として、そこからの差分を中心に解説しています。旧連載では、若干記述が古くて不正確な部分もありますが、一部はより深い解説をしていますので、適宜そちらも参照ください。


1. 今後の予想スケジュール


1.1. 標準化完了は2018年5月見込み →2019年2月見込み→2019年3月7日完了

現時点(2018年1月4日)は、CS(Committee Specification)01が発行されたところです。CS発行から標準化完了のOS(OASIS Standard)まで、約3か月強かかる予定ですので、若干の遅れも考慮に入れて、標準化完了は2018年5月と予想します。旧連載では2017年末と予想しましたが、約5か月遅れています。

CS発行からCOS(Candidate OASIS Standard)発行まで、なんと10か月以上を要しました。CSへのコメント反映であるCS2が5月に発行されましたが、その後、OASISの標準化ルールである「COS発行には、3つ以上の独立したstatement of use(その標準がインプリメント可能であることを証明する実装)が必要である」のため、statement of useが3つ揃うのを待っていました。ついに、HiveMQ、VerneMQ、Eclipse Pahoが揃ったため、COSにやっと移行できました。

※CS/COS/OSといった標準化タスクの説明は旧連載を参照ください。

なお、OASIS標準は、いわゆる「コミュニティー標準」であり、国際標準ではありません。前の版のMQTT3.1.1は、OASIS標準化から約1年半経過して、国際標準であるISO/IEC標準になりました。


1.2. 本格的利用が開始されるのは2019年度

現時点で、バージョン5の実装は、IBMが中心となって推進しているオープンソースであるEclipse Pahoが先行して着手しはじめています。Pahoでは各種言語向けのクライアントライブラリと、テストコードを提供しています。その後の状況は前節に記載の通りです。

しかし、Eclipse Mosquittoなどのブローカーでの実装はまだ始まっていません。バージョン5の更新範囲は膨大ですので、少しずつβ版での実装が進み、主要ブローカーでの実装が完了するのは、2018年度後半になると思われます。この予想は的中していました。よって以降の予想時期は変えません。2019/3/10追記 主要ブローカーで実装が進み、Mosquittoでもβ実装となっています。

よって、バージョン5が本格的に利用開始されるのは2019年度になると予想します。


1.3. メジャーに使われるようになるのは2021年度以降

新規のMQTTプロトコル実装が当然のごとくバージョン5を前提とするような「メジャー化」には、さらに2年を要すると予想します。


2. パケットフォーマット新旧比較

旧バージョンである3.1.1と比較しながら、パケットフォーマットを解説します。

共通で、以下のデータ型を利用しています。

本稿での略記
規格での型名
意味

Byte
Bits
1バイト数値または8ビットのフラグ

2-Bytes
Two Byte Integer
2バイト符号なし整数

4-Bytes
Four Byte Integer
4バイト符号なし整数

String
UTF-8 Encoded String
2バイト符号なし整数での文字列長、およびUTF-8文字列

Variable
Variable Byte Integer
可変長整数(0〜268,435,455)、整数の大きさによって1〜4バイトの可変長にエンコードされる

Binary
Binary Data
2バイト符号なし整数での長さ、およびバイナリ列

String Pair
UTF-8 String Pair
連続する2つのString

・・・

0個以上の繰り返しを示す


2.1. CONNECT

image.png


  • バージョン番号の内部表現が4から5に上がっています。

  • バージョン5から導入されたPropertyが、2箇所(CONNECTそのもののPropertyと、WILL Property)追加されています。

  • Connect Flag内の、Clean Sessionフラグが、Clean Startフラグに名称変更されています。Clean Sessionの役割が、Clean Startと、PropertyのSession Expiry Intervalの双方に分散されたからです。


2.2. CONNACK

image.png


  • 従来のReturn Codeが拡張され、Reason Codeに名称変更しました。

  • Propertyが追加されました。


2.3. PUBLISH

image.png


  • Propertyの追加が、唯一の変更点です。


2.4. PUBACK

image.png


  • Reason Codeがオプションで追加されました(Remaining Length=2なら不要で、Reason Code=0x00(Success)を意味します)。

  • Propertyがオプションで追加されました(Remaining Lengthが4未満なら不要)。


2.5. PUBREC

image.png


  • Reason Codeがオプションで追加されました(Remaining Length=2なら不要で、Reason Code=0x00(Success)を意味します)。

  • Propertyがオプションで追加されました(Remaining Lengthが4未満なら不要)。


2.6. PUBREL

image.png


  • Reason Codeがオプションで追加されました(Remaining Length=2なら不要で、Reason Code=0x00(Success)を意味します)。

  • Propertyがオプションで追加されました(Remaining Lengthが4未満なら不要)。


2.7. PUBCOMP

image.png


  • Reason Codeがオプションで追加されました(Remaining Length=2なら不要で、Reason Code=0x00(Success)を意味します)。

  • Propertyがオプションで追加されました(Remaining Lengthが4未満なら不要)。


2.8. SUBSCRIBE

image.png


  • Propertyが追加されました。

  • 従来のRequested QoSは、様々なフラグを追加することで拡張され、Subscription Optionに名称変更しました。(下図参照)

image.png


  • Subscription Optionに追加されたフラグの説明を、以下に示します。


    • NLとRAPは、Bridge型のブローカー実装に役立つように追加されました。


      • NL(No Local)オプションが1の場合、同一のClient IDからのメッセージ転送を禁止します。

      • RAP(Retain As Published)オプションが1の場合、コネクション確立済SUBSCRIBEに転送されるメッセージについて、転送前メッセージのRetainオプションを転送後も維持します。このオプションが0の場合、転送後のRetainオプションは一律0にセットされます。



    • RH(Retain Handling)オプションは以下の通りです。


      • 0の場合、SUBSCRIBE開始時点で全てのRetainメッセージが転送されます。

      • 1の場合、同一セッション内での新規のSUBSCIBEの場合だけRetainメッセージが転送されます。同一セッションの過去のコネクションで既にSUBSCRIBE済の場合はRetainメッセージは転送されません。(同一セッションの過去のコネクションにおいて受信したRetainメッセージを、再度受信しないですみます)

      • 2の場合、全てのRetainメッセージは転送されません。いずれの場合も、SUBSCRIBE中に受信したメッセージはRetainかどうかにかかわらず転送されます。






2.9. SUBACK

image.png


  • Propertyが追加されました。

  • 従来のReturn Codeが拡張され、Reason Codeに名称変更しました。


2.10. UNSUBSCRIBE

image.png


  • Propertyの追加が、唯一の変更点です。


2.11. UNSUBACK

image.png


  • Propertyが追加されました。

  • Payloadが必須となり、Reason Codeのリストを返すようになりました。


2.12. PINGREQ

image.png


  • 変更ありません。


2.13. PINGRESP

image.png


  • 変更ありません。


2.14. DISCONNECT

image.png


  • Variable Headerがオプションで記述可能(Remaining Length=0なら不要)となり、Reason Codeを返すようになりました。Remaining Length=0の場合、Reason Code=0x00(Normal disconnection)となります。

  • Propertyがオプションで追加されました(Remaining Lengthが2未満なら不要)。

  • バージョン5からの大きな追加として、ブローカーからDISCONNECTが送信可能になりました。


2.15. AUTH

image.png


  • バージョン5で新たに追加されたコントロールパケットです。CONNECTのPropertyでAuthentication Methodを指定すると、CONACKパケットを受け取るまでの間は、オプションでAUTHパケットをやりとりすることが可能になります。

  • Remaining Length=0の場合は、Reason Code=0x00(Success)かつPropertyなしを意味します。


3. 拡張されたReason Code

従来のReturn Codeが拡張され、バージョン5では、Reason Codeに名称変更するとともに、コマンドに依存しない一意(0x00を除く)の数値に再割り当てされました。正常を表すコードについてはv3.1.1からの互換性を維持するとともに、異常を表すコードは0x80以上にまとめられました。

一覧で解説します。

v3.1.1 CONNACK Return Code:

数値
名称
適用コマンド

0x00
Connection Accepted
CONNACK

0x01
Connection Refused, unacceptable protocol version
CONNACK

0x02
Connection Refused, identifier rejected
CONNACK

0x03
Connection Refused, Server unavailable
CONNACK

0x04
Connection Refused, bad user name or password
CONNACK

0x05
Connection Refused, not authorized
CONNACK

v3.1.1 SUBACK Return Code:

数値
名称
適用コマンド

0x00
Success - Maximum QoS 0
SUBACK

0x01
Success - Maximum QoS 1
SUBACK

0x02
Success - Maximum QoS 2
SUBACK

0x80
Failure
SUBACK

v5 Reson Code:

数値
名称
適用コマンド

0x00
Success
CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH

0x00
Normal disconnection
DISCONNECT

0x00
Granted QoS 0
SUBACK

0x01
Granted QoS 1
SUBACK

0x02
Granted QoS 2
SUBACK

0x04
Disconnect with Will Message
DISCONNECT

0x10
No matching subscribers
PUBACK, PUBREC

0x11
No subscription existed
UNSUBACK

0x18
Continue authentication
AUTH

0x19
Re-authenticate
AUTH

0x80
Unspecified error
CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT

0x81
Malformed Packet
CONNACK, DISCONNECT

0x82
Protocol Error
CONNACK, DISCONNECT

0x83
Implementation specific error
CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT

0x84
Unsupported Protocol Version
CONNACK

0x85
Client Identifier not valid
CONNACK

0x86
Bad User Name or Password
CONNACK

0x87
Not authorized
CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT

0x88
Server unavailable
CONNACK

0x89
Server busy
CONNACK, DISCONNECT

0x8A
Banned
CONNACK

0x8B
Server shutting down
DISCONNECT

0x8C
Bad authentication method
CONNACK, DISCONNECT

0x8D
Keep Alive timeout
DISCONNECT

0x8E
Session taken over
DISCONNECT

0x8F
Topic Filter invalid
SUBACK, UNSUBACK, DISCONNECT

0x90
Topic Name invalid
CONNACK, PUBACK, PUBREC, DISCONNECT

0x91
Packet Identifier in use
PUBACK, PUBREC, SUBACK, UNSUBACK

0x92
Packet Identifier not found
PUBREL, PUBCOMP

0x93
Receive Maximum exceeded
DISCONNECT

0x94
Topic Alias invalid
DISCONNECT

0x95
Packet too large
CONNACK, DISCONNECT

0x96
Message rate too high
DISCONNECT

0x97
Quota exceeded
CONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT

0x98
Administrative action
DISCONNECT

0x99
Payload format invalid
CONNACK, PUBACK, PUBREC, DISCONNECT

0x9A
Retain not supported
CONNACK, DISCONNECT

0x9B
QoS not supported
CONNACK, DISCONNECT

0x9C
Use another server
CONNACK, DISCONNECT

0x9D
Server moved
CONNACK, DISCONNECT

0x9E
Shared Subscriptions not supported
SUBACK, DISCONNECT

0x9F
Connection rate exceeded
CONNACK, DISCONNECT

0xA0
Maximum connect time
DISCONNECT

0xA1
Subscription Identifiers not supported
SUBACK, DISCONNECT

0xA2
Wildcard Subscriptions not supported
SUBACK, DISCONNECT


4. 新しく規定されたProperty

バージョン5から、新しくPropertyが規定されました。一覧で概説するとともに、いくつかについては詳細解説します。


4.1. 一覧

数値
名称
意味概説
データ型
適用コマンド

0x01
Payload Format Indicator
ペイロードフォーマット識別子(0:Binary、1:String)
Byte
PUBLISH, Will

0x02
Message Expiry Interval
メッセージの最大有効期間(秒)、メッセージ転送時に値を更新する
4-Bytes
PUBLISH, Will

0x03
Content Type
ペイロートフォーマット補足情報(例えばMIME Typeなど)
String
PUBLISH, Will

0x08
Response Topic
Request-Responseの返信Topic
String
PUBLISH, Will

0x09
Correlation Data
Request-Responseの相互共有情報(トランザクションIDなど)
Binary
PUBLISH, Will

0x0B
Subscription Identifier
Subscription ID
Variable
PUBLISH, SUBSCRIBE

0x11
Session Expiry Interval
セッションの最大維持期間(秒)
4-Bytes
CONNECT, CONNACK, DISCONNECT

0x12
Assigned Client Identifier
Client IDが指定されていない場合に、プローカーからClient IDを強制指定
String
CONNACK

0x13
Server Keep Alive
ブローカーからKeep Alive値(秒)を強制上書き
2-Bytes
CONNACK

0x15
Authentication Method
拡張認証の方式名
String
CONNECT, CONNACK, AUTH

0x16
Authentication Data
拡張認証の任意の補足データ
Binary
CONNECT, CONNACK, AUTH

0x17
Request Problem Information
詳細エラー情報の許可
Byte
CONNECT

0x18
Will Delay Interval
WILLの送信待機時間(秒)
4-Bytes
Will

0x19
Request Response Information
Request-Response参照情報の要求
Byte
CONNECT

0x1A
Response Information
Request-Response参照情報
String
CONNACK

0x1C
Server Reference
リダイレクト情報
String
CONNACK, DISCONNECT

0x1F
Reason String
詳細エラー情報等の任意の補足文字列
String
CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT, AUTH

0x21
Receive Maximum
QoS1/2のメッセージをレスポンスを待たずに同時送受信できる最大数(双方向それぞれ指定可能)
2-Bytes
CONNECT, CONNACK

0x22
Topic Alias Maximum
Topic Aliasの最大値(双方向それぞれ指定可能)
2-Bytes
CONNECT, CONNACK

0x23
Topic Alias
今回指定のTopic Aliasの値、Topic名をあわせて指定した場合はTopic Alias値の新規アサインもしくは再アサインを意味する
2-Bytes
PUBLISH

0x24
Maximum QoS
最大QoS
Byte
CONNACK

0x25
Retain Available
RETAINの許可
Byte
CONNACK

0x26
User Property
任意のユーザ定義プロパティ名と値文字列のペア(複数記述可能)
String Pair
CONNECT, CONNACK, PUBLISH, Will, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, DISCONNECT, AUTH

0x27
Maximum Packet Size
送受信可能な最大パケット長(双方向それぞれ指定可能)
4-Bytes
CONNECT, CONNACK

0x28
Wildcard Subscription Available
ワイルドカードの許可
Byte
CONNACK

0x29
Subscription Identifier Available
Subscription IDの許可
Byte
CONNACK

0x2A
Shared Subscription Available
共有Subscriptionの許可
Byte
CONNACK


4.2. 詳細解説


4.2.1. Request-Response

MQTTでは困難であったエンドツーエンドでのRequest-Responseパターンを実現する。


  • 応答側はしかるべき処理をした後、Response Topic宛てに応答を返信する。要求側は一般的にResponse TopicをSUBSCRIBEして待ち受ける。

  • 要求メッセージにCorrelation Dataが含まれている場合、応答側クライアントはその内容をコピーして、応答メッセージのCorrelation Dataに書き込むことで、要求と応答の関連付けが可能になる。これは、シーケンス番号などのトランザクションIDに利用可能である。

  • 要求側は任意の方法で応答トピックを決定することが可能。多くの場合、応答トピックはクライアントごとに一意なものになる。

  • オプションとして、CONNECT時にRequest Response Informationプロパティをセットして、サーバからクライアントに対応しトピックフリーなグローバルな応答トピック(クライアント個々のルートトピック等)を指定することで、個々のクライアントに応答トピックを定義せずに済む。

  • 関連するPropertyは、0x08(Response Topic)、0x09(Correlation Data)、0x19(Request Response Information)、0x1A(Response Information)。


4.2.2. Subscription ID

クライアントは、メッセージがどのSUBSCRIBEに一致したのかを簡単に判別することが可能で、それに基づくアクションにつなげることができる。


  • SUBSCRIBEトピックごとにオプション付与する。

  • セッション内で一意な値をとるが、新たな値で上書きすることも可能。クライアント側としては、セッションを超えて一意にする実装することが有用な場合が多い。

  • メッセージがどのSUBSCRIBEに一致したのかが、PUBLISHにおけるSubscription IDのリストで表現される。

  • 関連するPropertyは、0x0B(Subscription Identifier)、0x29(Subscription Identifier Available)。


4.2.3. 拡張認証

単純なBasic認証よりも強固な認証を利用することができる。


  • クライアントがCONNECTでAuth Methodを指定することにより、拡張認証が起動される。

  • CONNECTとCONNACKの間でAUTHパケットを交換することにより、チャレンジレスポンスなどが可能になる。

  • 関連するPropertyは、0x15(Authentication Method)、0x16(Authentication Data)。


4.2.4. Topic Alias

Topicをエイリアス値で代替することで、メッセージサイズを短縮することができる。


  • Topic Aliasと有効なトピックの組み合わせにより、Topic Aliasを設定または再設定できる。

  • Topic Aliasを設定または再設定すると、同一ネットワークコネクションの次のリクエストから、Topic Aliasと0バイトのトピックの組み合わせにより、同じトピックを指定したものとみなす。

  • 関連するPropertyは、0x22(Topic Alias Maximum)、0x23(Topic Alias)。


4.2.5. 共有Subscription

コンシューマとなるクライアントを複数並列させて負荷分散構成をとることができる。


  • 共有サブスクリプションでは、ただ1つのセッションにのみメッセージがPUBLISHされる。どのセッションにメッセージをPUBLISHするかは、ブローカーの実装依存。

  • トピック形式は、$share/{ShareName}/{filter} で表現される。

  • 関連するPropertyは、0x2A(Shared Subscription Available)。