Skip to content

Instantly share code, notes, and snippets.

@bamchoh
Last active February 28, 2022 22:59
Show Gist options
  • Save bamchoh/97a166761fad46aa1c7527c55aff28b2 to your computer and use it in GitHub Desktop.
Save bamchoh/97a166761fad46aa1c7527c55aff28b2 to your computer and use it in GitHub Desktop.
MQTT 3.1.1 日本語訳 (自分用)

MQTT 3.1.1 日本語訳 (自分用)

更新:2020-12-21
作者:@bamchoh
バージョン:0.01

注意

↓以下を日本語訳する。(自分用、意訳多々、TOEICレベル300点)

http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html

↓ここから翻訳

1. はじめに

1.1 MQTTの構成

1.2 用語

1.3 引用規定

1.4 参考文献

1.5 データ詳細

1.5.1 ビット

バイト内のビットは0から7までの番号が割り振られます。7ビット目は最上位ビットを表し、最下位ビットは0ビット目となります。

1.5.2 整数値

整数値はビッグエンディアン(上位バイトが下位バイトの先に来る)オーダーの16bit長で表されます。つまり、16bitワードはネットワーク上で上位バイトが先に送られ、次に下位バイトが送られるということです。

1.5.3 UTF-8 文字列

後に説明されるコントロールパケットの中のテキストフィールドはUTF-8文字列としてエンコードされる。UTF-8 [RFC3629] は Unicode文字列の効率的なエンコード方式です。Unicode文字列はテキストベースの通信を支えるアスキー文字列のエンコードを最適化します。

各文字列の先頭2バイトには文字列の長さを表すフィールドが付加されます。長さはバイトで表され、UTF-8でエンコードされた文字列が入ります。(例: 図 1.1) そのため、一つのUTF-8文字列が表せる長さには制限があります。つまり、65535バイトより大きい文字列は扱うことができません。

特に明記されていない限り、UTF-8文字列は0~65535 byteの範囲となります。

図 1.1 UTF-8文字列の構造

Bit 7 6 5 4 3 2 1 0
Byte 1 文字列の上位バイト(MSB)
Byte 2 文字列の下位バイト(LSB)
Byte 3 ... UTF-8 文字データ, (もし、長さが1以上なら付与)

UTF-8 でエンコードされた文字列は RFC3269 で示される Unicode 仕様に定義されている通りに 適切な UTF-8 コード でなければならない。 特に、このデータは U+D800 から U+DFFF の間のコードポイントのエンコーディングを 含めてはいけない。 もし、サーバーもしくはクライアントで無効なフォーマットのUTF-8文字列を含むコントロールパケットを受信した場合、ネットワーク接続を クローズしなければならない。 [MQTT1.5.3-1]

UTF-8文字列はヌル文字(U+0000)を 含めてはいけない。 もし、レシーバ(サーバー/クライアント)が U+0000 を含むコントロールパケットを受信した場合、ネットワーク接続を クローズしなければならない [MQTT-1.5.3-2].

文字列データには以下に示す Unicode コードポイントのエンコーディングを 含めるべきではない。 もし、レシーバ(サーバー/クライアント)がこれらのいずれかを含むコントロールパケットを受信した場合、ネットワーク接続が クローズされる場合がある。

  • U+0001 ~ U+001F 制御文字
  • U+007F ~ U+009F 制御文字
  • Unicode 仕様上、非文字として定義されているコードポイント (例: U+0FFFF)

UTF-8でエンコードされたシーケンス 0xEF 0xBB 0xBF はそれが文字列中のどこで出現しても、常に U+FEFF (ゼロ幅ノンブレークスペース) として解釈され、パケット受信者によってスキップしたり、削除したりしては ならない。 [MQTT-1.5.3-3]

1.5.3.1 参考例

例えば、ラテン語の大文字Aの後にコードポイント U+2A6D4 (CJK漢字拡張Bの文字の一つ) が続く A𪛔 という文字列は以下のようにエンコードされます。

図 1.2 UTF-8でエンコードされた文字列のnon-normativeな例

Bit 7 6 5 4 3 2 1 0
Byte 1 文字列長(上位バイト(MSB)) (0x00)
  0 0 0 0 0 0 0 0
Byte 2 文字列長(上位バイト(LSB)) (0x05)
  0 0 0 0 0 1 0 1
Byte 3 'A'(0x41)
  0 1 0 0 0 0 0 1
Byte 4 (0xF0)
  1 1 1 1 0 0 0 0
Byte 5 (0xAA)
  1 0 1 0 1 0 1 0
Byte 6 (0x9B)
  1 0 0 1 1 0 1 1
Byte 7 (0x94)
  1 0 0 1 0 1 0 0

1.6 文書内の特殊な構文の意味について

この仕様内の黄色で色付けされたテキストは適合性宣言を意味する。適合性宣言は[MQTT-x.x.x-y]という形の参照が割り当てられている。 (訳者注1: 適合性宣言はおそらく、この文章は必須で実装してね、という意味だと考えている) (訳者注2: 黄色で色塗りができてないので、本項の内容はこの文章内では意味しない)

2. MQTT コントロールパケットフォーマット

2.1 MQTT コントロールパケットの構造

MQTT プロトコルは一連のMQTTコントロールパケットを決まった形でやり取りすることで動作します。このセクションではそれらパケットのフォーマットを説明します。

MQTTコントロールパケットは大きく3つの部分で構成され、常に図2.1に示される通りの順序になります。

図 2.1 – MQTTコントロールパケットの構造

固定ヘッダー, 全てのMQTTコントロールパケットで付与される
可変ヘッダー, いくつかのMQTTコントロールパケットで付与される
ペイロード, いくつかのMQTTコントロールパケットで付与される

2.2 固定ヘッダー

Each MQTT Control Packet contains a fixed header. Figure 2.2 - Fixed header format illustrates the fixed header format.

各MQTTコントロールパケットは固定ヘッダーを持ちます。図2.2は固定ヘッダーフォーマットの内容になります。

図 2.2 – 固定ヘッダーのフォーマット

Bit 7 6 5 4 3 2 1 0
Byte 1 MQTT コントロールパケットのタイプ 各MQTT コントロールパケット固有のフラグ
Byte 2 残りの長さ

2.2.1 MQTT コントロールパケットタイプ

ポジション: Byte 1, 4 ~ 7 ビット目

4 ビット符号なしの値として表され、値の意味は下表の表2.1の通りです。

表 2.1 - コントロールパケットタイプ

名前 流れの向き 説明
Reserved 0 禁止 予約
CONNECT 1 クライアント -> サーバー クライアントがサーバーに接続するためにリクエストする
CONNACK 2 サーバー -> クライアント 接続 ACK
PUBLISH 3
クライアント -> サーバー
or
サーバー -> クライアント
メッセージを配信する
PUBACK 4
クライアント -> サーバー
or
サーバー -> クライアント
配信 ACK
PUBREC 5
クライアント -> サーバー
or
サーバー -> クライアント
配信 received (保証付き配信 part 1)
PUBREL 6
クライアント -> サーバ
or
サーバー -> クライアント
配信 release (保証付き配信 part 2)
PUBCOMP 7
クライアント -> サーバ
or
サーバー -> クライアント
配信 完了 (保証付き配信 part 3)
SUBSCRIBE 8 クライアント -> サーバー クライアント購読リクエスト
SUBACK 9 サーバー -> クライアント 購読 ACK
UNSUBSCRIBE 10 クライアント -> サーバー 購読解除要求
UNSUBACK 11 サーバー -> クライアント 購読解除 ACK
PINGREQ 12 クライアント -> サーバー PING リクエスト
PINGRESP 13 サーバー -> クライアント PING 応答
DISCONNECT 14 クライアント -> サーバー クライアントが切断した
Reserved 15 禁止 予約

2.2.2 フラグ

固定ヘッダー内のByte 1の残りのビット(0~3ビット目)は下表 2.2 にある通り、MQTTコントロールパケット毎のフラグを持つ。表中の"予約"となっているフラグは将来用に予約されており、値は表のとおりにセットされ なければならない [MQTT-2.2.2-1] もし、無効なフラグを受信した場合、受信者はネットワーク接続をクローズ しなければならない [MQTT-2.2.2-2] エラーハンドリングの詳細については 4.8章を参照。

表2.2 - フラグ ビット

コントロールパケット 固定ヘッダーフラグ ビット 3 ビット 2 ビット 1 ビット 0
CONNECT 予約 0 0 0 0
CONNACK 予約 0 0 0 0
PUBLISH Used in MQTT 3.1.1 DUP1 QoS2 QoS2 RETAIN3
PUBACK 予約 0 0 0 0
PUBREC 予約 0 0 0 0
PUBREL 予約 0 0 1 0
PUBCOMP 予約 0 0 0 0
SUBSCRIBE 予約 0 0 1 0
SUBACK 予約 0 0 0 0
UNSUBSCRIBE 予約 0 0 1 0
UNSUBACK 予約 0 0 0 0
PINGREQ 予約 0 0 0 0
PINGRESP 予約 0 0 0 0
DISCONNECT 予約 0 0 0 0

DUP1 = PUBLISHコントロールパケットの配信の重複

QoS2 = PUBLISHのサービス品質(QoS)

RETAIN3 = PUBLISH 保持フラグ

DUP, QoS, RETAINフラグの詳細については PUBLISHコントロールパケットの章内の3.3.1章を参照のこと。

2.2.3 残りの長さ

ポジション: Byte 2 のはじめ

残りの長さは可変ヘッダとペイロードのデータを含む現在のパケットの残りのバイト数を表します。残りの長さには残りの長さをエンコードするために使用するバイト含みません。

残りの長さは1バイト127までを使用する可変長エンコーディングスキーマを使用してエンコーディングします。それより大きな値は以下の通り処理されます。各バイトの下位7ビットはデータをエンコードし、最上位ビットは残りの長さを表すバイト列として次のバイトがあることを示すために仕様されます。したがって、各バイトは128個の値と"継続ビット"とで表されます。残りの長さフィールドの最大バイト数は4バイトです。

規約外コメント

例えば、10進整数 64 はシングルバイト(10進数で64, 16進数で0x40)として表されます。10進整数 321 (= 65 + 2*128) は下位バイトが先に来る2バイトでエンコードされます。最初のバイトは 65 + 128 = 193 です。この時の最上位ビットは少なくとも一つの後続するバイトがあることを示すためにセットされていることに注意が必要です。2バイト目は2です。

規約外コメント

これはアプリケーションに 268,435,455 (256MB)までのサイズのコントロールパケットを送信することを許可します。ワイヤー上ではこの数値は0xFF, 0xFF, 0xFF, 0x7F で表されます。

表 2.4 はバイト数の増分によって表現される残りの長さの値を示しています。

表2.4 残りの長さフィールドのサイズ

数値 開始値 終了値
1 0 (0x00) 127 (0x7F)
2 128 (0x80, 0x01) 16 383 (0xFF, 0x7F)
3 16 384 (0x80, 0x80, 0x01) 2 097 151 (0xFF, 0xFF, 7F)
4 2 097 152 (0x80, 0x80, 0x80, 0x01) 268 435 455 (0xFF, 0xFF, 0xFF, 0x7F)

規約外コメント

可変長エンコーディングスキーマ中の非負整数(X)をエンコーディングするためのアルゴリズムは以下の通りです:

do
    encodedByte = X MOD 128
    X = X DIV 128
    // if there are more data to encode, set the top bit of this byte
    if ( X > 0 )
      encodedByte = encodedByte OR 128
    endif
      'output' encodedByte

while ( X > 0 )

MOD は剰余演算(C言語でいうところの %)で、 DIV は除算演算(C言語でいうところの /)、そして OR は論理和演算(C言語でいうところの |)です。

規約外コメント

残りの長さフィールドをデコードするためのアルゴリズムは以下の通りです:

multiplier = 1
value = 0
do
  encodedByte = 'next byte from stream'
  value += (encodedByte AND 127) * multiplier
  multiplier *= 128
  if (multiplier > 128*128*128)
    throw Error(Malformed Remaining Length)
while ((encodedByte AND 128) != 0)

AND は論理積演算(C言語でいうところの &)です。

このアルゴリズムが終了すると、 value には残りの長さが格納されます。

2.3 可変長ヘッダー

MQTTコントロールパケットのいくつかのタイプは可変長ヘッダーコンポーネントを含みます。可変長ヘッダーは固定ヘダーとペイロードの間に位置します。可変長ヘッダーの内容はパケットタイプに依って様々に変化します。可変長ヘッダーのパケット識別子フィールドは様々なパケットタイプで共通のフィールドです。

2.3.1 パケット識別子

図2.3 パケット識別子バイト列

Bit 7 6 5 4 3 2 1 0
Byte 1 パケット識別子の上位バイト(MSB)
Byte 2 パケット識別子の下位バイト(LSB)

多くのコントロールパケットタイプの可変長ヘッダーコンポーネントは2バイトのパケット識別子ヘッダーフィールドを含みます。これらのコントロールパケットは次の通りです。 PUBLISH (QoSが0より大きい場合), PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK

SUBSCRIBE, UNSUBSCRIBE, と PUBLISH (QoSが0より大きい場合) のコントロールパケットは非ゼロ16ビットのパケット識別子が含まれて いなければなりません。 [MQTT2.3.1-1] クライアントがこれらコントロールパケットタイプのいずれかのパケットを送信する度にこれまで使用していないユニークなパケット識別子を割り当てなければ なりません [MQTT-2.3.1-2] もし、クライアントがパケット識別子を持つ特定のコントロールパケットを再送するなら、再送パケットには同じパケット識別子を使用しなければ なりません クライアントが ACKパケット(肯定応答)に対応するパケットを処理した後、同じパケット識別子は再利用可能となります。QoS 1 PUBLISH の場合、ACKパケットは PUBACK となります。 QoS2 の場合、 PUBCOMP となります。 SUBSCRIBE と UNSUBSCRIBE については、 SUBACK, UNSUBACK が該当します。 [MQTT-2.3.1-3] QoSが0より大きいPUBLISHを送信する場合、この条件はサーバー側にも適用されます。 [MQTT-2.3.1-4]

もし、QoS値に0がセットされているなら、PUBLISHパケットにはパケット識別子は含めてはいけません [MQTT-2.3.1-5]

PUBACK, PUBREC, PUBREL パケットは 送信されてきた PUBLISH パケットと同じパケット識別子を設定 しなければなりません。 [MQTT-2.3.1-6] 同じように、 SUBACK, UNSUBACK は 対応する SUBSCRIBE と UNSUBSCRIBE パケットそれぞれに使われたパケット識別子を含めなければ なりません。 [MQTT-2.3.1-7]

パケット識別子を要求するコントロールパケットは『表2.5 パケット識別子を持つコントロールパケット』に記載しています。

表2.5 パケット識別子を持つコントロールパケット

名前 パケット識別子フィールド
CONNECT NO
CONNACK NO
PUBLISH YES (if QoS > 0)
PUBACK YES
PUBREC YES
PUBREL YES
PUBCOMP YES
SUBSCRIBE YES
SUBACK YES
UNSUBSCRIBE YES
UNSUBACK YES
PINGREQ NO
PINGRESP NO
DISCONNECT NO

クライアントとサーバーはお互いに独立したパケット識別子を割り当てます。結果として、クライアント/サーバーペアは同じパケット識別子を使って並行なメッセージのやり取りに参加することができます。

規約外コメント

クライアントがPUBLISHパケットをパケット識別子 0x1234 で送信した後、サーバーから異なる PUBLISHパケットをパケット識別子 0x1234 で受け取ることができます。これは クライアントが送信したPUBLLISHパケットに対するPUBACKパケットを受信する前でも可能です。

Client Server

PUBLISH パケット識別子=0x1234---→

←--PUBLISH パケット識別子=0x1234

PUBACK パケット識別子=0x1234---→

←--PUBACK パケット識別子=0x1234

2.4 ペイロード

いくつかのMQTTコントロールパケットは第3章に記載されている通り、パケットの最終パートとしてペイロードを持ちます。PUBLISHパケットの場合、ペイロードはアプリケーションメッセージになります。『表2.6 ペイロードを含むコントロールパケット』にペイロードが必要なコントロールパケットがリストされています。

表2.6 ペイロードを含むコントロールパケット

コントロールパケット ペイロード
CONNECT 必須
CONNACK なし
PUBLISH 任意
PUBACK なし
PUBREC なし
PUBREL なし
PUBCOMP なし
SUBSCRIBE 必須
SUBACK 必須
UNSUBSCRIBE 必須
UNSUBACK なし
PINGREQ なし
PINGRESP なし
DISCONNECT なし

3. MQTT コントロールパケット

3.1 CONNECT (クライアントからサーバーへのコネクションリクエスト)

クライアントによるサーバーへのネットワーク接続が確率した後、クライアントからサーバーに送信される最初のパケットとしてCONNECTパケットが送信されなければ なりません [MQTT-3.1.0-1]

クライアントはCONNECTパケットをネットワーク接続上に一度だけ送信することができます。クライアントから2番目のCONNECTパケットが送信されてきた場合、サーバーはプロトコル違反が発生したものと判断し、クライアントとの接続を切断 しなければなりません [MQTT-3.1.0-2] エラーハンドリングについては 4.8章を参照してください。

ペイロードは一つ以上のエンコードされたフィールドを含みます。それらはユニークなクライアント識別子(トピック、メッセージ、ユーザー名やパスワード)を明示します。クライアント識別子以外は任意で、それらの存在は可変長ヘッダー内のフラグに依って決定されます。

3.1.1 固定ヘッダー

図3.1 CONNECTパケット固定ヘッダー

Bit 7 6 5 4 3 2 1 0
Byte 1 MQTT コントロールパケットのタイプ (1) 予約領域
  0 0 0 1 0 0 0 0
Byte 2 残りの長さ

残りの長さフィールド

「残りの長さ」は可変長ヘッダー(10バイト)の長さ + ペイロードの長さとなります。それは 2.2.3章に記載されている手順に従ってエンコードされます。

3.1.2 可変長ヘッダー

CONNECTパケットの可変長ヘッダーは次の順番の4つのフィールドで構成されている:

  • プロトコル名
  • プロトコルレベル
  • 接続フラグ
  • キープアライブ

3.1.2.1 プロトコル名

図3.2 「プロトコル名」 バイト

  詳細 7 6 5 4 3 2 1 0
プロトコル名
byte 1 長さ 上位バイト (0) 0 0 0 0 0 0 0 0
byte 2 長さ 下位バイト (4) 0 0 0 0 0 1 0 0
byte 3 'M' 0 1 0 0 1 1 0 1
byte 4 'Q' 0 1 0 1 0 0 0 1
byte 5 'T' 0 1 0 1 0 1 0 0
byte 6 'T' 0 1 0 1 0 1 0 0

「プロトコル名」は プロトコル名である "MQTT" を表すUTF-8でエンコードされた文字列で、すべて大文字です。この文字列はMQTTの仕様として未来永劫変わることのないものです。

もしプロトコル名が間違っていた場合、サーバーはクライアントの接続を接続する かもしれませんし 、他の仕様に従って CONNECT パケットの処理を継続する かもしれません 小文字の場合は、サーバーはこの仕様に則って CONNECT パケットを処理する べきではない [MQTT-3.1.2-1]

規約外コメント

ファイアウォールのようなパケットインスペクタは「プロトコル名」を使うことで MQTTのトラフィックを識別することができるでしょう。

3.1.2.2 プロトコル レベル

図3.3 「プロトコル レベル」バイト

  詳細 7 6 5 4 3 2 1 0
プロトコル レベル
byte 7 レベル (4) 0 0 0 0 0 1 0 0

クライアントが使用するプロトコルのリビジョンレベルを表す符号なし8ビット値。プロトコルバージョン 3.1.1 の場合は、プロトコルレベルは 4 (0x04) になります。 もしプロトコルレベルがサーバーで未サポートのレベルだった場合、サーバーはCONNECTパケットに対して、CONNACK を戻り値 0x01 (受け入れられないプロトコルレベル) で応答し、クライアントとの接続を切断 しなければなりません [MQTT-3.1.2-2]

3.1.2.3 接続フラグ

接続フラグはMQTT接続の振る舞いを示すいくつかのパラメータが含まれます。また、ペイロード中のフィールドのあるなしも示します。

図3.4 接続フラグビット

  7 6 5 4 3 2 1 0
 
ユーザー名
フラグ
パスワード
フラグ
保持
遺言
QoS
遺言
遺言
フラグ
クリーン
セッション
予約

byte 8 X X X X X X X 0

3.1.2.4 クリーン・セッション

位置: 接続フラグバイトの1ビット目

このビットではセッション状態のハンドリングを指定します。

クライアントとサーバーはセッション状態を保存し、信頼性のあるメッセージングを可能とし、ネットワークシーケンス全体を継続することができます。このビットはセッション状態の生存期間のコントロールするのに使われます。

もし「クリーン・セッション」が 0 なら、サーバーは(クライアント識別子で識別されるように)現在のセッション状態に基づいてクライアントとの接続を維持 しなければなりません もし、クライアントに関連付けされていないセッションがないなら、サーバーは新しいセッションを作成 しなければなりません クライアントとサーバーが切断された後、セッションは保存 しなければなりません [MQTT-3.1.2-4] 「クリーン・セッション」が 0 に設定されたセッションの切断後、サーバーは、セッションの一部として切断時にクライアントが持っていたサブスクリプションと一致する QoS1 と QoS2 のメッセージを追加で保存する 必要があります [MQTT-3.1.2-5] また、同じ要件を満たす QoS0 メッセージも保存 してもよい

もし「クリーン・セッション」が 1 なら、クライアントとサーバーは以前のセッションを破棄し、新しいセッションを 始めなければなりません このセッションはネットワーク接続が続く限り存続します。このセッションに紐づいた状態データは副シーケンスセッション内で再利用 してはならない [MQTT-3.1.2-6]

クライアント内のセッション状態は以下を含みます:

  • サーバーに送信されてはいるが、完全に確認(ACK)されていない QoS 1 と QoS 2 メッセージ
  • サーバーから受信したが、完全に確認(ACK)されていない QoS 2 メッセージ

サーバー内のセッション状態は以下を含みます:

  • 存在しているセッション (セッション状態の残りが空であっても)
  • クライアントのサブスクリプション
  • クライアントへ送信されてはいるが、完全に確認(ACK)されていない QoS 1 と QoS 2 メッセージ
  • クライアントへの転送を保留している QoS 1 と QoS 2 メッセージ
  • クライアントから受信したが、完全に確認(ACK)されていない QoS 2 メッセージ
  • オプションで、クライアントへの転送を保留している QoS 0 メッセージ

保持メッセージはサーバーのセッション状態の一部とはならず、セッションが終了する時に削除されては なりません [MQTT-3.1.2.7]

保存された状態の詳細と制限については4.1章を参照してください。

「クリーン・セッション」が1に設定されているとき、クライアントとサーバーは状態の削除を不可分(atomically)に行う必要はありません。

規約外コメント

不成功の場合に一貫性のある状態を保証するために、クライアントは接続が成功するまで、「クリーン・セッション」を 1 に設定して繰り返し接続を試みるべきです。

規約外コメント

一般的に、クライアントは常に「クリーン・セッション」を 0 か 1 に設定して接続し、これら2つの値を交換しません。どちらを選択するかはアプリケーションに依存します。「クリーン・セッション」を1に設定したクライアントは古いアプリケーションメッセージを受信しませんし、接続する度に関心のあるトピックを新たに購読する必要があります。値が 0 に設定された「クリーン・セッション」を使用したクライアントは切断中に発行されたすべての QoS1 または QoS2 のメッセージを受信します。従って、切断中のメッセージロスを起こさないことを保証するには、「クリーン・セッション」を 0 に設定した QoS1 か QoS2 を使用します。

規約外コメント

クライアントが「クリーン・セッション」を 0 で接続する時、サーバーに切断した後もMQTTセッション状態を維持することを要求します。クライアントは後でサーバーに再接続する際に「クリーン・セッション」を 0 に設定して接続する必要があります。クライアントはセッションをそれ以上使用しないと判断した場合、最後の接続を「クリーン・セッション」を 1 に設定して接続し、そして切断しなければなりません。

3.1.2.5 Will フラグ

位置: 接続フラグバイトの2ビット目

Willフラグが1にセットされているなら、それは次のことを示しています、「もし接続リクエストが受理されたなら、Willメッセージはサーバーに保存され、ネットワーク接続に関連付けられ なければなりません DISCONNECTパケットの受信時にサーバーによってWillメッセージが削除されていない限りネットワーク接続がその後閉じられた時に Will メッセージを発行し なければなりません 」 [MQTT-3.1.2-8]

Willメッセージが発行される状況は以下を含みますが、これらに限りません:

  • サーバー側で I/O エラーもしくは ネットワークエラーを検知した
  • Keep Alive の時間内にクライアントからの応答がない
  • DISCONNECTパケットなしにクライアントがネットワーク接続を閉じる
  • サーバーがプロトコルエラーを理由にネットワーク接続を閉じる

Willフラグが1にセットされているなら、Connect フラグ中の Will QoS と Will Retain フィールドはサーバーによって使われ、Will トピックと Willメッセージフィールドはペイロード内に なければなりません [MQTT-3.1.2-9]

Willメッセージは一旦送信されるか、サーバーがクライアントから DISCONNECTパケットを受信したら、削除され なければなりません [MQTT-3.1.2-10]

Willフラグが0にセットされているなら、Connect フラグ中の WIll QoS と Will Retain フィールドは 0 がセットされ、WillトピックとWillメッセージフィールドはペイロード中に あってはなりません [MQTT-3.1.2-11]

Willフラグが0にセットされているなら、Willメッセージはネットワーク接続が終わるタイミングで発行しては いけません [MQTT-3.1.2-12]

サーバーはWillメッセージを即座に発行 すべきです サーバーがシャットダウンしたり、なにがしかのエラーが発生した場合、その後再起動するまでWillメッセージの発行はおそらく遅延するでしょう。もしそのようなことが発生すると、サーバーに障害が発生してから、Willメッセージが発行されるまでの間に遅延が発生する可能性があります。

3.1.2.6 Will QoS

位置: 接続フラグバイトの3,4ビット目

これら2ビットはWillメッセージを発行するときに使われるQoSレベルを示します。

Willフラグが0に設定されているなら、Will QoS は 0 (0x00) に設定し なければなりません [MQTT-3.1.2-13]

Willフラグが1に設定されているなら、Will QoS の値は 0 (0x00), 1 (0x01), 2 (0x02) にできます。 3 (0x03) に してはいけません [MQTT-3.1.2-14]

3.1.2.7 Will Retain

位置: 接続フラグバイトの5ビット目

このビットはWillメッセージが発行された時に保持されるかどうかを示します。

Willフラグが 0 に設定されているなら、Will Retain フラグは 0 にセット しなければなりません [MQTT-3.1.2-15]

Willフラグが 1 に設定されていて、

  • Will Retain が 0 にセットされているなら、サーバーはWillメッセージは非保持メッセージとして発行 しなければなりません [MQTT-3.1.2-16]
  • Will Retain が 1 にセットされているなら、サーバーはWillメッセージは保持メッセージとして発行 しなければなりません [MQTT-3.1.2-17]

3.1.2.8 ユーザー名 フラグ

位置: 接続フラグバイトの7ビット目

ユーザー名フラグが0にセットされているなら、ユーザー名がペイロード内に存在 してはいけません [MQTT-3.1.2-18]

ユーザー名フラグが1にセットされているなら、ユーザー名がペイロード内に存在 しなければなりません [MQTT-3.1.2-19]

3.1.2.9 パスワード フラグ

位置: 接続フラグバイトの6ビット目

パスワードフラグが0に設定されているなら、パスワードはペイロード内に存在 してはいけません [MQTT-3.1.2-20]

パスワードフラグが1に設定されているなら、パスワードはペイロード内に存在 しなければなりません [MQTT-3.1.2-21]

ユーザー名フラグが0に設定されているなら、パスワードフラグは0に設定 されなければなりません [MQTT-3.1.2-22]

3.1.2.10 Keep Alive

図3.5 Keep Alive バイト

ビット 7 6 5 4 3 2 1 0
byte 9 Keep Alive 上位バイト(MSB)
byte 10 Keep Alive 下位バイト(LSB)

Keep Alive 秒単位で測定される時間間隔です。16ビットワードで表現され、クライアントがコントロールパケットを送信完了してから次を送信するまでに経過して良い最大の時間間隔を表します。コントロールパケットを送信している間の間隔がKeep Alive値を超えないようにするのはクライアントの責任です。他にどのコントロールパケットの送信がない時、クライアントは PINGREQ パケットを送信 しなければなりません [MQTT-3.1.2-23]

クライアントは PINGREQ を Keep Alive 値とは無関係に任意のタイミングで送信でき、 PINGRESP をネットワーク、サーバーが動いていることを認識するために使用することができます。

Keep Alive が 非ゼロで、サーバーがクライアントからコントロールパケットをKeep Alive時間の1.5倍の時間内で受信しないなら、サーバーはネットワークエラーが発生したかのようにクライアントとのネットワーク接続を切断 しなければなりません [MQTT-3.1.2-24]

クライアントがPINGREQを送信した後、適切な時間内にPINGRESPパケットを受信しなかったなら、サーバーとのネットワーク接続をクローズ すべきです

ゼロ (0) の Keep Alive は Keep Alive メカニズムを無効にします。つまり、不活性を理由にクライアントとの接続を切断することをサーバーに要求しません。 サーバーはクライアントから提供された Keep Alive とは関係なく、任意のタイミングで不活性や不応答を判断したクライアントを切断することを許容することに注意してください。

規約外コメント

Keep Alive の実際の値はアプリケーション依存で、一般的にこれは数秒です。最大値は18時間12分15秒です。

3.1.2.11 Variable ヘッダー 規約外サンプル

図3.6 Variable ヘッダー 規約外サンプル

  詳細 7 6 5 4 3 2 1 0
プロトコル名
byte 1 長さ 上位バイト (0) 0 0 0 0 0 0 0 0
byte 2 長さ 下位バイト (4) 0 0 0 0 0 1 0 0
byte 3 'M' 0 1 0 0 1 1 0 1
byte 4 'Q' 0 1 0 1 0 0 0 1
byte 5 'T' 0 1 0 1 0 1 0 0
byte 6 'T' 0 1 0 1 0 1 0 0
プロトコル レベル
byte 7 レベル (4) 0 0 0 0 0 1 0 0
接続 フラグ
byte 8
ユーザー名 フラグ (1)
パスワード フラグ (1)
Will Retain フラグ (0)
Will QoS フラグ (01)
Will フラグ (1)
クリーン・セッション (1)
予約 (0)
1 1 0 0 1 1 1 0
Keep Alive
byte 9 Keep Alive 上位バイト (0) 0 0 0 0 0 0 0 0
byte 10 Keep Alive 下位バイト (10) 0 0 0 0 1 0 1 0

3.1.3 ペイロード

CONNECT パケットのペイロードは可変長ヘッダーで存在を決定づけられた一つ以上の長さフィールドをもちます。これらフィールドがもしあるなら、クライアント識別子、遺言トピック、遺言メッセージ、ユーザー名、パスワードの順で現れ なければなりません [MQTT-3.1.3-1]

3.1.3.1 クライアント識別子

クライアント識別子(クライアントID) はサーバーに対してクライアントを識別します。サーバーに接続している各クライアントはユニークなクライアントIDを持ちます。クライアントIDはサーバー・クライアント間のMQTTセッションに関連して保持している状態を認識するために、クライアントとサーバーで使われ 無ければならない [MQTT-3.1.3-2]

クライアント識別子(クライアントID) は CONNECT パケットのペイロードの初めのフィールドに存在し なければならない [MQTT-3.1.3-3]

クライアントID 1.5.3 章で定義されている通り、UTF-8でエンコードされた文字列で なければならない

サーバーは以下の文字種のみが含まれる UTF-8でエンコードされた長さ 1~23バイトの間のクライアントIDを許容し なければならない [MQTT-3.1.3-5]

文字種: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

サーバーは23バイトより大きいサイズのクライアントIDを許容する 可能性がある。 サーバーは上記の文字種以外の文字種も許容する 可能性がある。

サーバーはクライアントに 0バイトの長さのクライアントIDを提示することを許可する 可能性がある。 しかしながら、その場合サーバーはこれを特殊ケースとして扱わ なければならず 、このクライアントにユニークなクライアントIDを割り当て なければならない。 [MQTT-3.1.3-6]

もし、クライアントが 0バイトのクライアントIDを提示するなら、クライアントは クリーン・セッションも 1とし なければならない [MQTT-3.1.3-7]

もし、クライアントが 0バイトのクライアントIDをクリーン・セッションの値を0にして提示したなら、サーバーは CONNACK リターンコードを 0x02 (識別子の却下) にした CONNECT パケットを応答し なければならない。 そしてその後、ネットワーク接続を切断し なければならない。 [MQTT-3.1.3-8]

もし、サーバーがクライアントIDを却下するなら、CONNACKのリターンコードを0x02(識別子の却下)にしたCONNETパケットを応答し なければならない。 そしてその後、ネットワークを切断し なければならない。 [MQTT-3.1.3-9]

規約外のコメント

クライアントの実装によってはランダムなクライアントIDを生成する便利なメソッドを提供する可能性があるが、クリーン・セッションが0に設定されている場合は、そのようなメソッドの使用は控えるべきである。

3.1.3.2 遺言トピック

If the Will Flag is set to 1, the Will Topic is the next field in the payload. The Will Topic MUST be a UTF-8 encoded string as defined in Section 1.5.3 [MQTT-3.1.3-10].

3.1.3.3 Will Message

If the Will Flag is set to 1 the Will Message is the next field in the payload. The Will Message defines the Application Message that is to be published to the Will Topic as described in Section 3.1.2.5. This field consists of a two byte length followed by the payload for the Will Message expressed as a sequence of zero or more bytes. The length gives the number of bytes in the data that follows and does not include the 2 bytes taken up by the length itself.

When the Will Message is published to the Will Topic its payload consists only of the data portion of this field, not the first two length bytes.

3.1.3.4 User Name

If the User Name Flag is set to 1, this is the next field in the payload. The User Name MUST be a UTF-8 encoded string as defined in Section 1.5.3 [MQTT-3.1.3-11]. It can be used by the Server for authentication and authorization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment