Skip to content

ファイル転送クライアント開発

このページでは、クライアント視点でのファイル転送プロセスの概要と、EMQXへのファイルアップロードに関する詳細なコマンド情報を提供します。クライアント側のファイル転送機能開発の支援を目的としています。

ファイル転送プロセス

既存のMQTT接続を再利用しつつ、クライアントは特定のプレフィックスを持つトピックにあらかじめ定められたメッセージをパブリッシュすることで、ファイル転送セッションを制御できます。

クライアント側のファイル転送プロセスは以下の通りです:

  1. 転送準備:クライアントデバイスはアップロードするファイルを選択し、転送セッションを識別するための一意のfile_idを生成します。
  2. ファイル転送の初期化:クライアントデバイスは$file/{file_id}/initトピックにinitコマンドをパブリッシュします。メッセージはJSON形式で、ファイル名、サイズ、チェックサムなどのファイルメタデータを含みます。
  3. 分割ファイル転送:クライアントは$file/{file_id}/{offset}[/{checksum}]トピックに連続してメッセージをパブリッシュし、ファイルを転送します。メッセージ内容は現在のファイルセグメントのデータブロックで、オプションでデータブロックのチェックサムを示すchecksumフィールドを含めることができます。
  4. ファイル転送の完了:クライアントは$file/{file_id}/fin/{file_size}[/{checksum}]トピックにfinコマンドをパブリッシュし、ファイル転送の完了を示します。メッセージ内容は空で、file_sizeパラメータはファイルの総サイズを示し、checksumフィールドはファイル全体のチェックサムです。

各転送コマンドの詳細な説明や注意点については、以下のセクションをご参照ください。

EMQX ファイル転送プロセス

ファイル転送コマンド

ファイル転送コマンドは、特定のトピック形式とメッセージ内容を持つMQTTメッセージです:

  • トピック:トピックプレフィックスには$file/$file-async/があり、それぞれ同期転送と非同期転送に使用されます。同一ファイル転送セッション内で異なるコマンドに混在して使用可能です。
    • 同期転送:クライアントはEMQXによるコマンド実行結果の確認を待ってから次の操作に進みます。
    • 非同期転送:クライアントはEMQXのコマンド実行確認を待たずに、コマンド送信後すぐに新たなコマンドを送信でき、処理速度が向上します。
  • QoS:すべてのコマンドは信頼性確保のためQoSレベル1でパブリッシュされます。
  • メッセージ本文:JSON形式またはデータブロックを含むメッセージ本文となります。

各コマンド送信後、コマンド実行結果はPUBACKメッセージまたはレスポンストピックで取得可能です。詳細はコマンド実行結果の取得をご覧ください。

TIP

  1. すべてのファイル転送コマンドはEMQXブローカーで処理され、他のMQTTクライアントには送信されません。
  2. 非同期転送モードはEMQX v5.3.2以降で利用可能です。
  3. MQTT v3.1/v3.1.1クライアントではPUBACK Reason Codeが利用できないため、非同期転送モードの使用を推奨します。

init コマンド

initコマンドはファイル転送セッションを初期化するために使用します。

  • トピック:$file/{file_id}/init または $file-async/{file_id}/init

  • メッセージ本文:以下のフィールドを持つJSONオブジェクト

    json
    {
      "name": "{name}",
      "size": {size},
      "checksum": "{checksum}",
      "expire_at": {expire_at},
      "segments_ttl": {segments_ttl},
      "user_data": {user_data}
    }
フィールド説明
file_idファイル転送セッションを識別する一意のID。
nameファイル名。予約語(例:"."、"..")と衝突する場合や特殊文字を含む場合はパーセントエンコードされます。ファイル名のバイナリ長は240バイト以内が推奨されます。
sizeファイルサイズ。
checksumファイルのSHA256チェックサム(任意)。指定するとEMQXがファイルのチェックサムを検証します。
expire_atストレージからファイルが削除される可能性のあるタイムスタンプ(エポック秒)。
segments_ttlファイルセグメントの有効期間(秒)。minimum_segments_ttlmaximum_segments_ttlで制限されます。詳細はセグメントストレージを参照。
user_dataファイルに関する追加情報やメタデータを格納する任意のJSONオブジェクト。

メッセージ本文で必須なのはnameフィールドのみです。

例:

json
{
  "name": "ml-logs-data.log",
  "size": 12345,
  "checksum": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
  "expire_at": 1696659943,
  "segments_ttl": 600
}

segment コマンド

segmentコマンドはファイルのデータブロックをアップロードするために使用します。

  • トピック:$file/{file_id}/{offset}[/{checksum}] または $file-async/{file_id}/{offset}[/{checksum}]
  • メッセージ本文:ファイルブロックのバイナリデータ
フィールド説明
file_idファイル転送セッションを識別する一意のID。
offsetファイルの先頭からのバイト単位の開始オフセット。
checksumファイルブロックのSHA256チェックサム(任意)。

fin コマンド

finコマンドはファイル転送セッションを完了するために使用します。

  • トピック:$file/{file_id}/fin/{file_size}[/{checksum}] または $file-async/{file_id}/fin/{file_size}[/{checksum}]
  • メッセージ本文:空のメッセージ本文
フィールド説明
file_idファイル転送セッションを識別する一意のID。
file_sizeファイルの総サイズ(バイト単位)。
checksumファイル全体のSHA256チェックサム(任意)。指定するとinitコマンドのchecksumより優先されます。

finコマンドを受信後、EMQXはファイルを組み立てるために必要なすべてのセグメントが受信済みか検証します。ファイルのエクスポートが成功しチェックサムが有効な場合、EMQXは成功のReason Codeで応答します。エラーがある場合は適切なエラー応答が送信されます。

コマンド実行結果の取得

コマンド実行結果はMQTTのPUBACK Reason Codeで示されます:

  • 同期転送:PUBACKのReason Codeが操作の最終結果を表します。
  • 非同期転送:非ゼロのPUBACK Reason Codeは即時の失敗を示し、ゼロのReason Codeはコマンドが処理受理されたことを示します。結果は処理完了後にレスポンスメッセージで返されます。

PUBACK Reason Codes

Reason CodeMQTTでの意味ファイル転送での意味
None0x00と同じ意味。
0x00成功ファイルブロックが正常にパーシステンスされた。
0x10該当するサブスクライバーなしサーバーはクライアントに全ファイルブロックの再送を要求。
0x80未指定のエラーsegmentコマンドの場合は現在のファイルブロックの再送を、finコマンドの場合は全ファイルブロックの再送を要求。
0x83特定のエラーサーバーはクライアントに送信のキャンセルを要求。
0x97クォータ超過サーバーはクライアントに送信の一時停止を要求。クライアントは再送まで待機すべき。

レスポンスメッセージ

  • トピック:$file-response/{clientId} (clientIdはクライアントID)
  • メッセージ:レスポンス結果を含むJSONオブジェクト

例:

json
{
  "vsn": "0.1",
  "topic": "$file-async/[COMMAND]",
  "packet_id": 1,
  "reason_code": 0,
  "reason_description": "success"
}
フィールド説明
vsnレスポンスメッセージフォーマットのバージョン
topic応答対象のコマンドトピック(例:$file-async/somefileid/init
packet_id応答対象のコマンドのMQTTメッセージID
reason_codeコマンドの実行結果コード。詳細はReason Codes参照
reason_description実行結果の説明

クライアントは同期・非同期に関わらず、$file-response/{clientId}トピックを通じてコマンドの実際の操作結果を取得できます。

注意事項

  1. ファイル転送中にクライアントが切断された場合や、優先度の高いメッセージ送信のために転送を中断する必要がある場合は、未アックのデータブロックやコマンドを再送するだけで問題ありません。これによりファイル全体の再送を避け、転送効率を向上させます。
  2. EMQXは受信したファイルセグメントからファイルを組み立て、設定されたストレージにエクスポートするため、finコマンドの処理には時間がかかる場合があります。この間、クライアントは他のコマンド送信を継続可能です。finコマンド処理中に切断が発生した場合は、単にコマンドを再送することでファイル転送を再開できます。すでに転送完了している場合は、EMQXが即座に成功応答を返します。

クライアントコード例

各種言語・クライアントライブラリでのファイル転送クライアントコード例を参照できます: