WHITE PAPER
Driving the Future of Connected Cars with MQTT →

MQTT Reason Code の紹介と参考資料

EMQX Team
Nov 24, 2023
MQTT Reason Code の紹介と参考資料

Reason Code

MQTTの Reason Code の主な目的は、より詳細なフィードバックをクライアントとサーバーに提供することです。たとえば、間違ったユーザー名またはパスワードに対応する Reason Code を CONNACK パケットでクライアントにフィードバックすると、クライアントは接続できない理由を知ることができます。

MQTT 3.1.1 の Reason Code

MQTT 3.1.1 はすでに Reason Code をサポートしていますが、利用可能な Reason Code の多くは定義されていません。実際、それらは非常に限られています。

Reason Code をサポートする2 つのMQTT パケットのうち、CONNACK パケットには失敗を示す Reason Code が 5 つだけあります。また、SUBACK パケットには失敗を示す Reason Code が 1 つだけあり、サブスクリプション失敗の理由についての詳細を提供することさえできません。さらに、 Reason Code をサポートしていない公開や購読解除などの操作の場合、操作が成功したかどうかさえ判断できません。これにより、開発デバッグが不親切になり、堅牢なコードの実装が妨げられます。

MQTT 5.0 の Reason Code

そのため、MQTT 5.0 では、使用可能な Reason Code の数が 43 に拡張され、0x80 未満の Reason Code は成功を示すために使用され、0x80 以上の Reason Code は失敗を示すために使用されることが指定されています。MQTT 3.1.1 とは異なり、0x80 未満の Reason Code も失敗を示す可能性があります。これにより、クライアントは操作が成功したかどうかを迅速に判断できるようになります。

さらに、MQTT 5.0 では、 Reason Code のサポートが、CONNACK、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBACK、UNSUBACK、DISCONNECT、および AUTH のパケットに拡張されています。現在では、メッセージのパブリッシュが成功したかどうかを判断できるだけでなく、一致するサブスクライバーが存在しない、特定のトピックにパブリッシュするための権限が不十分であるなど、失敗の理由も理解できるようになりました。

Reason Code in MQTT 5.0

SUBACK と UNSUBACK を除き、ほとんどの MQTT パケットには Reason Code が 1 つだけ含まれます。これは、SUBSCRIBE パケットと UNSUBSCRIBE パケットには複数のトピック フィルターを含めることができ、各トピック フィルターには操作の結果を示す対応する Reason Code が必要であるためです。したがって、SUBACK および UNSUBACK パケットは複数の Reason Code に対応する必要があります。そのため、他のパケットの Reason Code は変数ヘッダーに配置され、SUBACK および UNSUBACK の Reason Code はペイロードに配置されます。

MQTT packets

この記事の最後の Reason Code クイック リファレンス テーブルでは、MQTT 5.0 の各 Reason Code の詳細な説明と使用例を提供しました。詳細については、こちらをご覧ください。

接続が切断された理由をクライアントに示します

MQTT 3.1 および 3.1.1 では、DISCONNECT パケットはクライアントによってのみ送信できました。したがって、クライアントが特定の制限に違反した場合、サーバーは追加情報をクライアントに提供せずにネットワーク接続を直接閉じることしかできませんでした。このため、切断の原因を調査することが困難になりました。

MQTT 5.0 では、サーバーはネットワーク接続を閉じる前に DISCONNECT パケットをクライアントに送信できるようになりました。クライアントは、DISCONNECT パケット内の Reason Code を使用して、パケットが大きすぎる、サーバーがビジーであるなど、接続が切断された理由を取得できます。

Reason String

Reason String は MQTT 5.0 の Reason Code を補完するもので、診断目的で設計された人間が判読できる文字列を提供します。 Reason Code はほとんどのエラー理由を示すことができますが、開発者やオペレーターはさらに直感的なコンテキスト情報を必要とする場合があります。

たとえば、サーバーが Reason Code (0x8F) を使用してクライアントに無効なトピック フィルターを示した場合、開発者はその理由に関する具体的な情報をまだ持っていません。トピックレベルの最大数を超えているか、サーバーで受け入れられない文字が含まれていることが原因ですか? ただし、サーバーが「トピック レベルの数が制限を超えています。最大は 10 です」のような Reason Stringを返すことができれば、開発者は理由をすぐに理解し、調整することができます。

実際の使用では、Reason String の内容はクライアントとサーバーの特定の実装によって異なります。したがって、正しく実装された受信側は、Reason String の内容を解析しようとするべきではありません。推奨される使用法には、例外をスローするときやログに書き込むときに Reason Stringを使用することが含まれますが、これに限定されません。

最後に、Reason String はオプションの機能であり、Reason String が受信されるかどうかは、ピアがそれをサポートしているかどうかによって決まります。

MQTT 5.0 Reason Code の参考テーブル

コード ネーム パケット 詳細説明
0x00 Success CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH この Reason Code は、CONNACK、DISCONNECT パケットなど、 Reason Code を持つすべてのパケットで使用できます。通常、接続の成功、サブスクライブの解除の成功、パケットの受信の成功、認証の成功など、成功を示すために使用されます。
0x00 Normal disconnection DISCONNECT DISCONNECT パケットでは、 Reason Code 0 は通常の切断を示し、Will メッセージは公開されません。
0x00 Granted QoS 0 SUBACK SUBACK パケット内の 0、1、2 は、購読結果を示すために使用されます。これらはすべて、正常なサブスクリプションを表すと同時に、サブスクライバに付与される最大 QoS レベルを示します。0、1、および 2 は、3 つの QoS レベルに正確に対応します。これは、サーバーによって許可される最大 QoS レベルが、加入時に要求される最大 QoS レベルよりも小さい可能性があるためです。たとえば、サブスクリプション中に要求された最大 QoS レベルが 2 であるが、サーバーが QoS 1 のみをサポートしている場合などです。
0x01 Granted QoS 1 SUBACK -
0x02 Granted QoS 2 SUBACK -
0x04 Disconnect with Will Message DISCONNECT DISCONNECT パケットにのみ使用され、クライアントが通常どおりに切断したいが、サーバーが引き続き will メッセージを発行する必要がある状況に適しています。たとえば、クライアントはセッションの有効期限の通知を受け取りたいとします。
0x10 No matching subscribers PUBACK, PUBREC この Reason Code は、メッセージが受信されたことを送信者に示すために使用されますが、現在一致するサブスクライバーが存在しないため、サーバーのみがこの Reason Code を使用できます。応答パケットを受信することで、誰もメッセージを受信しないことがわかります。 Reason Code 0x10 の応答メッセージを受信しますが、加入者が 1 人以下でない限り、 Reason Code 0x10 の応答メッセージを受信しなくても全員がメッセージを受信するとは限りません。ただし、加入者が 0x00 の場合は 0x00 の代わりに 0x10 を使用することに注意してください。一致するサブスクライバが存在しないという動作は必須の動作ではなく、サーバーの特定の実装によって異なります。
0x11 No subscription existed UNSUBACK UNSUBACK パケットにのみ使用され、サブスクライブ解除時に一致するサブスクリプションが見つからなかったことを示します。
0x18 Continue authentication AUTH AUTH パケットにのみ使用され、認証の継続を意味します。この Reason Code を通じて、さまざまな認証方法のニーズを満たすために、クライアントとサーバーの間で任意の数の AUTH パケットを交換できます。
0x19 Re-authenticate AUTH AUTH パケットにのみ使用されます。拡張認証が成功した後、クライアントは Reason Code 0x19 を含む AUTH パケットを送信することで、いつでも再認証を開始できます。再認証中、他のパケットの送受信は通常どおり続行されます。再認証に失敗した場合、接続は切断されます。
0x80 Unspecified error CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT 特定できないエラーを示します。一方の当事者がエラーの具体的な原因を他方の当事者に開示したくない場合、またはプロトコル仕様の現在の状況に一致する Reason Code がない場合、パケット内でこの Reason Code を使用できます。
0x81 Malformed Packet CONNACK, DISCONNECT プロトコル仕様に従って正しく解析できない制御パケットを受信した場合、受信側は Reason Code 0x81 を含む DISCONNECT パケットを送信して切断する必要があります。CONNECT パケットに問題がある場合、サーバーは CONNACK パケットを使用する必要があります。プロトコル要件に従って固定ヘッダーの予約ビットが 0 に設定されていない場合、QoS は 3 に指定され、UTF-8 文字列は制御パケットにヌル文字が含まれている場合、不正な形式のパケットとみなされます。
0x82 Protocol Error CONNACK, DISCONNECT 制御パケットがプロトコル仕様に従って解析された後に検出されたエラー(プロトコルで許可されていないデータ、プロトコル要件と一致しない動作など)は、プロトコル エラーとみなされます。受信側は、 Reason Code 0x81 の DISCONNECT パケットを送信する必要があります。接続を解除します。CONNECT パケットに問題がある場合、サーバーは CONNACK パケットを使用する必要があります。一般的なプロトコル エラーには、クライアントが 1 つの接続内で 2 つの CONNECT パケットを送信すること、1 つのパケットに複数の同一のプロパティが含まれること、プロパティがプロトコルで許可されていない値に設定されていることが含まれます。ただし、他のより具体的な Reason Code がある場合は、0x81 (不正なパケット) や 0x82 (プロトコル エラー) は使用しません。たとえば、サーバーは保持メッセージをサポートしていないと宣言しましたが、クライアントは依然としてメッセージを送信します。これは本質的にプロトコル エラーですが、エラーの原因をより明確に示すことができる 0x9A (保持はサポートされていません) を使用することを選択します。
0x83 Implementation specific error CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT パケットは有効ですが、現在の受信者の実装では受け入れられません。
0x84 Unsupported Protocol Version CONNACK CONNACK パケットにのみ使用されます。MQTT 5.0 をサポートするサーバーの場合、クライアントが現在使用している MQTT プロトコルのバージョンがサポートされていない場合、またはクライアントが間違ったプロトコル バージョンまたはプロトコル名を指定した場合。たとえば、クライアントがプロトコル バージョンを 6 に設定するとします。この場合、サーバーは Reason Code 0x84 を含む CONNACK パケットを送信し、プロトコル バージョンがサポートされていないことと、MQTT ブローカーとしての ID を示し、ネットワークを閉じることができます。もちろん、MQTT 3.1 または 3.1.1 を使用するMQTT クライアントは Reason Code 0x84 の意味を理解できない可能性があるため、サーバーはネットワーク接続を直接閉じることを選択することもできます。どちらのバージョンも、CONNACK パケットで 0x01 を使用して、クライアントが指定したプロトコル バージョンがサポートされていないことを示します。
0x85 Client Identifier not valid CONNACK CONNACK パケットにのみ使用され、クライアント ID が有効な文字列であるが、サーバーがそれを許可していないことを示します。考えられる状況としては、クリーン スタートが 0 であるが、クライアント ID が空であるか、クライアント ID がサーバーで許可されている最大長を超えているなどです。
0x86 Bad User Name or Password CONNACK CONNACK パケットにのみ使用され、クライアントが間違ったユーザー名またはパスワードを使用したことを示します。つまり、クライアントは接続を拒否されます。
0x87 Not authorized CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT クライアントがトークン認証または拡張認証を使用する場合、クライアントの接続が許可されていないことを示すには 0x86 よりも 0x87 を使用する方が適切です。クライアントがパブリッシュやサブスクライブなどの操作を実行するとき、サーバーの許可チェックが行われない場合は、認証が渡された場合、サーバーは、PUBACK などの応答パケットに Reason Code 0x87 を指定して、認証結果を示すこともできます。
0x88 Server unavailable CONNACK 現在のサーバーが利用できないことをクライアントに示すために CONNACK パケットでのみ使用されます。たとえば、サーバーの認証サービスで問題が発生し、新しいクライアントを受け入れることができないことを示している可能性があります。
0x89 Server busy CONNACK, DISCONNECT これは、サーバーがビジー状態であることをクライアントに示します。後でもう一度試してください。
0x8A Banned CONNACK CONNACK パケットにのみ使用され、クライアントのログインが禁止されていることを示します。たとえば、サーバーがクライアントの異常な接続動作を検出したため、クライアントのクライアント ID または IP アドレスがブラックリストに追加されるか、バックグラウンド管理者に追加されます。クライアントを手動でブロックします。もちろん、上記は通常、特定のサーバーの実装に依存します。
0x8B Server shutting down DISCONNECT DISCONNECT パケットにのみ使用され、サーバーのみが使用できます。サーバーがシャットダウン中、またはシャットダウンしようとしている場合、 Reason Code 0x8B を持つ DISCONNECT パケットをアクティブに送信して、サーバーがシャットダウンしているために接続が終了したことをクライアントに通知できます。これにより、クライアントは、接続が閉じられた後にサーバーへの接続要求を開始し続けることを回避できます。
0x8C Bad authentication method CONNACK, DISCONNECT サーバーがクライアントによって指定された拡張認証方法をサポートしていない場合、またはクライアントが再認証中に前回の認証とは異なる認証方法を使用する場合、サーバーは Reason Code 0x8C を持つ CONNACK または DISCONNECT パケットを送信します。
0x8D Keep Alive timeout DISCONNECT DISCONNECT パケットにのみ使用され、サーバーのみが使用できます。クライアントがキープアライブ時間の 1.5 倍以内に通信を維持できない場合、サーバーは Reason Code 0x8D の DISCONNECT パケットを送信し、ネットワーク接続を閉じます。
0x8E Session taken over DISCONNECT DISCONNECT パケットにのみ使用され、サーバーのみが使用できます。クライアントがサーバーに接続するとき、サーバーに同じクライアント ID を使用するクライアント接続がすでに存在する場合、サーバーは Reason Code 0x8E の DISCONNECT パケットを送信します。既存のクライアントに送信し、セッションが新しいクライアントに引き継がれたことを示します。その後、サーバーは現在のクライアントのネットワーク接続を閉じます。新しいクライアント接続のクリーン スタートが 0 か 1 かに関係なく、サーバーはこの Reason Code を使用して、セッションが引き継がれたことを既存のクライアントに示します。
0x8F Topic Filter invalid SUBACK, UNSUBACK, DISCONNECT トピック フィルターは整形式ですが、サーバーによって受け入れられません。たとえば、トピック フィルターのレベルがサーバーで許可されている最大制限を超えているか、トピック フィルターに現在のサーバーで受け入れられない文字 (スペースなど) が含まれています。
0x90 Topic Name invalid CONNACK, PUBACK, PUBREC, DISCONNECT トピック名は正しい形式ですが、クライアントまたはサーバーによって受け入れられません。
0x91 Packet Identifier in use PUBACK, PUBREC, SUBACK, UNSUBACK これは、パケットで受信したパケット ID がすでに使用されていることを意味します。たとえば、送信者がパケット ID 100 の QoS 1 パケットを送信したが、受信者は、メッセージ フローがまだ完了していない同じパケット ID を使用する QoS 2 パケットがあると信じている場合、これは通常、パケット間の現在のセッション状態を示しています。クライアントとサーバーが一致しません。Clean Start を 1 に設定して再接続することにより、セッション状態をリセットする必要がある場合があります。
0x92 Packet Identifier not found PUBREL, PUBCOMP 対応するパケット ID が見つからないことを示します。これは QoS 2 パケット交換プロセス中にのみ発生します。たとえば、受信者が PUBREC パケットで応答した場合、送信者は同じパケット ID で確認を待っている PUBLISH パケットを見つけられません。または、送信者が PUBREL パケットを送信した場合、受信者は同じパケットを持つ PUBREC パケットを見つけられません。 ID。これは通常、クライアントとサーバー間の現在のセッション状態が一致していないことを意味し、クリーン スタートを 1 に設定して再接続することにより、セッション状態をリセットする必要がある場合があります。
0x93 Receive Maximum exceeded DISCONNECT DISCONNECT パケットにのみ使用され、最大受信値を超えたことを示します。MQTT 5.0 ではフロー制御メカニズムが追加されています。接続時に、クライアントとサーバーは、受信最大プロパティ (QoS > 0) を通じて同時に処理できる信頼できるメッセージの数について合意します。そのため、送信者が送信する未確認メッセージの数がこの制限を超えると、受信者は送信します。 Reason Code 0x93 の DISCONNECT パケットを送信し、ネットワーク接続を閉じます。
0x94 Topic Alias invalid DISCONNECT DISCONNECT パケットにのみ使用され、サブジェクト エイリアスが無効であることを示します。PUBLISH パケット内のトピック エイリアス値が 0 または接続中に合意されたトピック エイリアスの最大値よりも大きい場合、受信側はこれをプロトコル エラーとみなします。 Reason Code 0x94 の DISCONNECT パケットを送信し、ネットワーク接続を閉じます。
0x95 Packet too large CONNACK, DISCONNECT これは、パケットが最大許容サイズを超えていることを示すために使用されます。クライアントとサーバーが許可する最大パケット サイズは、CONNECT パケットと CONNACK パケットの最大パケット サイズ属性で指定できます。一方が大きすぎるパケットを送信すると、他方は Reason Code 0x95 の DISCONNECT パケットを送信します。クライアントは接続時に will メッセージを設定できるため、CONNECT パケットはサーバーが処理できる最大メッセージ サイズ制限を超える場合もあります。この場合、サーバーは CONNACK パケットでこの Reason Code を使用する必要があります。
0x96 Message rate too high DISCONNECT DISCONNECT パケットにのみ使用され、許可される最大メッセージ パブリケーション レートを超えたことを示します。この Reason Code と「クォータ超過」の違いに注意することが重要です。メッセージ レートは、1 秒あたりに公開できるメッセージの最大数など、メッセージの公開速度を制限します。一方、クォータは、クライアントが 1 日に公開できるメッセージの最大数など、リソースの割り当てを制限します。ただし、クライアントは 1 時間以内にクォータを使い果たす可能性があります。
0x97 Quota exceeded CONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT クォータ制限を超えたことを示すために使用されます。サーバーは、毎日最大 1000 件のメッセージの転送を許可するなど、パブリッシャーの送信クォータを制限する場合があります。パブリッシャーがクォータを使い果たすと、サーバーは PUBACK などの確認パケットでこの Reason Code を使用してパブリッシャーに通知します。一方、サーバーはクライアントの接続数とサブスクリプション数を制限することもあります。この制限を超えると、サーバーは現在クォータを超過していることを CONNACK または SUBACK パケットを通じてクライアントに示します。一部の厳格なクライアントとサーバーは、ピアが検出した場合に DISCONNECT パケットを送信し、接続を閉じることを選択する場合があります。ノルマを超えました。
0x98 Administrative action DISCONNECT DISCONNECT パケットにのみ使用され、管理者がバックグラウンドでクライアント接続をキックアウトするなどの管理操作により接続が閉じられたことをクライアントに示します。
0x99 Payload format invalid CONNACK, PUBACK, PUBREC, DISCONNECT Payload Format Indicator プロパティがパケットに含まれている場合、受信者はメッセージ内のペイロード形式がこのプロパティと一致するかどうかを確認できます。一致しない場合、受信側は Reason Code 0x99 の確認パケットを送信する必要があります。一部の厳密なクライアントまたはサーバーは、DISCONNECT パケットを直接送信してネットワーク接続を閉じる場合があります。CONNECT パケットの will メッセージに問題がある場合は、サーバーは Reason Code 0x99 の CONNACK パケットを送信し、ネットワーク接続を閉じます。
0x9A Retain not supported CONNACK, DISCONNECT サーバーが保持メッセージをサポートしていないが、クライアントがメッセージを送信する場合、サーバーは Reason Code 0x9A を含む DISCONNECT パケットを送信し、ネットワーク接続を閉じます。クライアントは接続時にメッセージを保持するように設定することもできるため、サーバーはこの Reason Code を CONNACK パケットで使用することもできます。
0x9B QoS not supported CONNACK, DISCONNECT 現在の QoS レベルがサポートされていないことを示すために使用されます。メッセージ (ウィル メッセージを含む) でクライアントによって指定された QoS が、サーバーによってサポートされる最大 QoS より大きい場合、サーバーは Reason Code 0x9B を持つ DISCONNECT または CONNACK パケットを送信し、ネットワーク接続を閉じます。ほとんどの場合、この Reason Code はサーバーによって使用されます。ただし、クライアントがサブスクリプションからではないメッセージを受信し、そのメッセージの QoS がサポートする最大 QoS を超えている場合も、 Reason Code 0x9B を持つ DISCONNECT パケットを送信し、ネットワーク接続を閉じます。この状況は通常、サーバーの実装に問題がある可能性があることを意味します。
0x9C Use another server CONNACK, DISCONNECT サーバーは、CONNACK または DISCONNECT パケットでこの Reason Code を使用して、一時的に別のサーバーに切り替える必要があることをクライアントに通知します。別のサーバーがクライアントに認識されていない場合は、この Reason Code もサーバー参照プロパティと一緒に使用する必要があります。新しいサーバーのアドレスをクライアントに通知します。
0x9D Server moved CONNACK, DISCONNECT サーバーは、CONNACK または DISCONNECT パケットでこの Reason Code を使用して、別のサーバーに永続的に切り替える必要があることをクライアントに通知します。別のサーバーがクライアントに認識されていない場合は、この Reason Code もサーバー参照プロパティと一緒に使用する必要があります。新しいサーバーのアドレスをクライアントに通知します。
0x9E Shared Subscriptions not supported SUBACK, DISCONNECT サーバーが共有サブスクリプションをサポートしていないが、クライアントが共有サブスクリプションを確立しようとしている場合、サーバーは Reason Code 0x9E を含む SUBACK パケットを送信してサブスクリプション要求を拒否するか、 Reason Code 0x9E を含む DISCONNECT パケットを直接送信してから、ネットワーク接続を閉じます。
0x9F Connection rate exceeded CONNACK, DISCONNECT クライアントが接続速度制限を超えたことを示すために使用されます。サーバーはクライアントの接続速度を制限できます。クライアントの接続が速すぎる場合、サーバーは Reason Code 0x9F を含む CONNACK パケットを送信して、新しい接続を拒否することがあります。もちろん、これは絶対的なシナリオではありません。すべてのクライアントが再接続するまでしばらく待機するわけではないため、一部のサーバー実装では CONNACK を返す代わりに接続を一時的に中断することを選択する場合があります。
0xA0 Maximum connect time DISCONNECT DISCONNECT パケットにのみ使用され、サーバーのみが使用できます。セキュリティ上の理由から、サーバーは 1 回の認証でクライアントの最大接続時間を制限できます。たとえば、JWT 認証を使用する場合、JWT の有効期限が切れた後はクライアント接続を継続すべきではありません。この場合、サーバーは Reason Code 0xA0 を含む DISCONNECT パケットを送信して、許可された最大接続時間が経過したために接続が閉じられたことをクライアントに示すことができます。を超えています。この Reason Code を含む DISCONNECT パケットを受信した後、クライアントは認証資格情報を再取得して、再度接続を要求できます。
0xA1 Subscription Identifiers not supported SUBACK, DISCONNECT サーバーがサブスクリプション識別子をサポートしていないが、クライアントのサブスクリプション要求にサブスクリプション識別子が含まれている場合、サーバーは Reason Code 0xA1 を持つ SUBACK パケットを送信してサブスクリプション要求を拒否するか、 Reason Code 0xA1 を持つ DISCONNECT パケットを直接送信して閉じることができます。ネットワーク接続。
0xA2 Wildcard Subscriptions not supported SUBACK, DISCONNECT サーバーがワイルドカード サブスクリプションをサポートしていないが、クライアントのサブスクリプション要求にトピック ワイルドカードが含まれている場合、サーバーは Reason Code 0xA2 を持つ SUBACK パケットを送信してサブスクリプション要求を拒否するか、 Reason Code 0xA2 を持つ DISCONNECT パケットを直接送信してネットワークを閉じることができます。繋がり。
無料トライアルEMQX Cloud
IoT向けフルマネージド型MQTTサービス
無料トライアル →

おすすめ閲読

Oct 10, 2023Zibo Zhou
MQTT QoS 0、1、2 のクイックスタート

MQTT プロトコルは、さまざまなネットワーク環境下でのメッセージ配信の信頼性を保証する 3 つの QoS (Quality of Service) レベルを指定します。