在裝置中使用以 AWS IoT MQTT 為基礎的檔案傳遞 - AWS IoT Core

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在裝置中使用以 AWS IoT MQTT 為基礎的檔案傳遞

如要啟動資料傳輸程序,裝置必須接收初始資料集,其至少包含串流 ID。在任務文件中含括初始資料集,您可使用 任務 來排程裝置的資料傳輸任務。當設備接收到初始數據集時,它應該開始與 AWS IoT 基於 MQTT 的文件傳遞進行交互。若要以 AWS IoT MQTT 為基礎的檔案傳送交換資料,裝置應該:

您可選擇性地在初始資料集中包含串流檔案 ID 和串流版本。將串流檔案 ID 傳送至裝置可簡化裝置韌體/軟體的程式設計,因為其不需要提出 DescribeStream 請求來取得此 ID。裝置可指定 GetStream 請求中的串流版本,強制執行一致性檢查,以防串流意外更新。

用 DescribeStream 於獲取流數據

AWS IoT 基於 MQTT 的文件傳遞提供了將流數據發送到設備的 DescribeStream API。此 API 傳回的串流資料包括串流 ID、串流版本、串流說明和串流檔案清單,每個檔案都有一個檔案 ID 和檔案大小 (以位元組為單位)。裝置可利用此資訊來選取任意檔案以啟動資料傳輸程序。

注意

若您的裝置在初始資料集中收到所有必要的串流檔案 ID,您無須使用 DescribeStream API。

請依照下列步驟提出 DescribeStream 請求。

  1. 訂閱「已接受」主題篩選條件 $aws/things/ThingName/streams/StreamId/description/json

  2. 訂閱「已拒絕」主題篩選條件 $aws/things/ThingName/streams/StreamId/rejected/json

  3. 將訊息傳送至 $aws/things/ThingName/streams/StreamId/describe/json 來發佈 DescribeStream 請求。

  4. 若接受該請求,您的裝置將會在「已接受」主題篩選條件上收到 DescribeStream 回應。

  5. 若請求遭到拒絕,您的裝置將會在「已拒絕」主題篩選條件上收到錯誤回應。

注意

若您在顯示的主題和主題篩選條件中將 json 替換為 cbor,您的裝置將會收到 CBOR 格式的訊息,這比 JSON 更精簡。

DescribeStream 請求

JSON 中的典型 DescribeStream 請求看起來會如下列範例所示。

{ "c": "ec944cfb-1e3c-49ac-97de-9dc4aaad0039" }
  • (選用) "c" 為用戶端字符欄位。

    用戶端字符不可超過 64 個位元組。長於 64 個位元組的用戶端字符會造成錯誤回應及 InvalidRequest 錯誤訊息。

DescribeStream 回應

JSON 中的 DescribeStream 回應看起來會如下列範例所示。

{ "c": "ec944cfb-1e3c-49ac-97de-9dc4aaad0039", "s": 1, "d": "This is the description of stream ABC.", "r": [ { "f": 0, "z": 131072 }, { "f": 1, "z": 51200 } ] }
  • "c" 為用戶端字符欄位。若其提供於 DescribeStream 請求中,則會傳回。使用用戶端字符,使回應與其請求產生關聯。

  • "s" 是整數形式的串流版本。您可使用此版本,對您的 GetStream 請求執行一致性檢查。

  • "r" 包含串流中的一份檔案清單。

    • "f" 是整數形式的串流檔案 ID。

    • "z" 是以位元組數為單位的串流檔案大小。

  • "d" 包含串流的說明。

從串流檔案取得資料區塊

您可使用 GetStream API,裝置便可接收小型資料區塊形式的串流檔案,因此其可供處理大型區塊大小有限制的裝置使用。如要接收整個資料檔案,裝置可能需要傳送或接收多個請求和回應,直至所有資料區塊已接收並加以處理為止。

GetStream 請求

請依照下列步驟提出 GetStream 請求。

  1. 訂閱「已接受」主題篩選條件 $aws/things/ThingName/streams/StreamId/data/json

  2. 訂閱「已拒絕」主題篩選條件 $aws/things/ThingName/streams/StreamId/rejected/json

  3. GetStream 請求發佈至主題 $aws/things/ThingName/streams/StreamId/get/json

  4. 若接受該請求,您的裝置將會在「已接受」主題篩選條件上收到一個或多個 GetStream 回應。每個回應訊息包含一個單一區塊的基本資訊和資料承載。

  5. 重複步驟 3 和 4,以接收所有資料區塊。若請求的資料量大於 128 KB,您必須重複這些步驟。您必須設定裝置的程式,來使用多個 GetStream 請求,以接收所有請求的資料。

  6. 若請求遭到拒絕,您的裝置將會在「已拒絕」主題篩選條件上收到錯誤回應。

注意
  • 若您在顯示的主題和主題篩選條件中將 "json" 替換為 "cbor",您的裝置將會收到 CBOR 格式的訊息,這比 JSON 更精簡。

  • AWS IoT 以 MQTT 為基礎的檔案傳遞會將區塊的大小限制為 128 KB。若您對超過 128 KB 的區塊提出請求,請求將會失敗。

  • 您可對總大小大於 128 KB 的多個區塊提出請求 (例如,若您對總量為 160 KB 的資料提出 5 個區塊 (每個區塊 32 KB) 的請求)。在這種情況下,請求不會失敗,但是您的設備必須提出多個請求才能接收請求的所有數據。當您的裝置提出其他請求時,服務會傳送其他區塊。我們建議您僅於正確接收並處理先前的回應之後,才可繼續進行新的請求。

  • 無論所請求的資料大小總量為何,您都應該將裝置設定為在未收到區塊或未正確收到區塊時啟動重試。

JSON 中的典型 GetStream 請求看起來會如下列範例所示。

{ "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380", "s": 1, "f": 0, "l": 4096, "o": 2, "n": 100, "b": "..." }
  • [選用] "c" 為用戶端字符欄位。

    用戶端字符不能超過 64 位元組。長於 64 個位元組的用戶端字符會造成錯誤回應及 InvalidRequest 錯誤訊息。

  • [選用] "s" 為串流版本欄位 (一個整數)。

    MQTT 型檔案交付會依據此請求的版本和雲端中的最新串流版本套用一致性檢查。若從 GetStream 請求中的裝置傳送的串流版本與雲端中最新串流版本不相符,則服務會傳送錯誤回應及 VersionMismatch 錯誤訊息。一般而言,裝置會在初始資料集或 DescribeStream 的回應中接收預期的 (最新的) 串流版本。

  • "f" 是串流檔案 ID (範圍為 0 到 255 的整數)。

    使用或 SDK 建立或更新串流時,需要串流檔案 ID。 AWS CLI 若裝置請求 ID 不存在的串流檔案,則服務會傳送錯誤回應和 ResourceNotFound 錯誤訊息。

  • "l" 為以位元組為單位的資料區塊大小 (範圍為 256 到 131,072 的整數)。

    請參閱 建立 GetStream 要求的點陣圖,以取得有關如何使用點陣圖欄位來指定 GetStream 回應中將會傳回之串流檔案部分的說明。若裝置指定一個超出範圍的區塊大小,則服務會傳送錯誤回應和 BlockSizeOutOfBounds 錯誤訊息。

  • [選用] "o" 為串流檔案中區塊的偏移量 (範圍為 0 到 98,304 的整數)。

    請參閱 建立 GetStream 要求的點陣圖,以取得有關如何使用點陣圖欄位來指定 GetStream 回應中將會傳回之串流檔案部分的說明。98,304 的最大值是以 24 MB 串流檔案大小限制為基礎,最小區塊大小為 256 個位元組。若未指定,則預設值為 0。

  • [選用] "n" 為請求的區塊數量 (範圍為 0 到 98,304 的整數)。

    "n" 欄位指定 (1) 請求的區塊數量,或 (2) 使用點陣圖欄位 ("b") 時,點陣圖請求將會傳回區塊數量的限制。此第二次使用是可選的。如果未定義,則預設值為 131072/ DataBlockSize

  • [選用] "b" 是個代表所請求區塊的點陣圖。

    使用點陣圖,您的裝置可以請求不連續的區塊,這使得在錯誤後處理重試更為方便。請參閱 建立 GetStream 要求的點陣圖,以取得有關如何使用點陣圖欄位來指定 GetStream 回應中將會傳回之串流檔案部分的說明。對此欄位,請將點陣圖轉換為以十六進記法表示點陣圖值的字串。點陣圖必須小於 12,288 個位元組。

重要

應指定 "n" 或 "b"。如果未指定,當檔案大小小於 131072 位元組 (128 KB) 時,GetStream 請求可能無效。

GetStream 回應

對於請求的每個資料區塊,JSON 中的 GetStream 回應看似此範例。

{ "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380", "f": 0, "l": 4096, "i": 2, "p": "..." }
  • "c" 為用戶端字符欄位。若其提供於 GetStream 請求中,則會傳回。使用用戶端字符,使回應與其請求產生關聯。

  • "f" 為目前資料區塊承載所屬串流檔案的 ID。

  • "l" 為資料區塊承載的大小 (以位元組為單位)。

  • "i" 為包含於承載中的資料區塊 ID。資料區塊的編號從 0 開始。

  • "p" 包含資料區塊承載。此欄位是一個字串,表示以 Base64 編碼的資料區塊值。

建立 GetStream 要求的點陣圖

您可使用 GetStream 請求中的點陣圖欄位 (b),從串流檔案獲取非連續區塊。此有助於 RAM 容量有限的裝置處理網路交付問題。裝置僅能請求那些未接收或未正確接收的區塊。點陣圖決定將會傳回的串流檔案區塊。對於點陣圖中設定為 1 的每個位元,會傳回串流檔案相對應的區塊。

下列範例說明如何在 GetStream 請求中指定點陣圖及其支援欄位。例如,您想要以 256 個位元組 (區塊大小) 的區塊接收串流檔案。將每個 256 個位元組的區塊視為具有一個數字,指定其在檔案中的位置,從 0 開始。所以區塊 0 是檔案中第一個 256 個位元組的區塊,區塊 1 是第二個區塊,依此類推。您想要從該檔案請求區塊 20、21、24 和 43。

區塊偏移

因為第一個區塊為數字 20,請指定偏移 (欄位 o) 為 20 以節省點陣圖中的空間。

區塊的數量

為確保您的裝置不會收到超過其在有限記憶體資源下可處理的區塊數,您可指定 MQTT 型檔案交付傳送的每則訊息中應傳回的區塊數量上限。請注意,若點陣圖本身指定的區塊數量小於此數,或者其讓 MQTT 型檔案交付傳送的回應訊息總大小大於每個 GetStream 請求 128 KB 的服務限制,則會忽略此值。

區塊點陣圖

點陣圖本身是一個以十六進記法表示的無符號位元組陣列,包含於 GetStream 請求中作為數字的字串表示。但若要建構此字串,讓我們先將點陣圖視為一長串的位元 (二進制數)。若在此序列中的某個位元設定為 1,則串流檔案相對應的區塊將會傳送回裝置。對於我們的範例,我們想要接收區塊 20、21、24 和 43,因此我們必須在點陣圖中設定位元 20、21、24 和 43。我們可以使用區塊偏移來節省空間,因此在我們從每個區塊減去偏移量之後,我們要設定位元 0、1、4 和 23,如下列範例所示。

1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

一次取一個位元組 (8 位元),這通常會寫成:"0b00010011"、"0b00000000" 和 "0b10000000"。位元 0 出現在我們的二進製表示中的第一個位元組末尾,位元 23 出現在最後一個位元組的開頭。除非您知道慣例,否則這可能會令人困擾。第一個位元組包含位元 7-0 (依該順序),第二個位元組包含位元 15-8,第三個位元組包含位元 23-16,依此類推。於十六進記法中,此會轉換為 "0x130080"。

提示

您可將標準二進制轉換為十六進記法。一次取四個二進制數字,並將其轉換為相對應的十六進制。例如,"0001" 變成 "1","0011" 變成 "3" 等等。

用於在 GetStream 請求中構建字符串的塊位圖細分。

綜上所述,我們 GetStream 請求的 JSON 如下所示。

{ "c" : "1", "s" : 1, "l" : 256, "f" : 1, "o" : 20, "n" : 32, "b" : "130080" }
  • "c" 為用戶端字符欄位。

  • s」是預期串流版本。

  • "l" 為資料區塊承載的大小 (以位元組為單位)。

  • f」是來源檔案索引的 ID。

  • o」是區塊位移。

  • n」是區塊數量。

  • b」是從位移開始遺失的區塊點陣圖。此值必須是 based64 編碼。

處理以 AWS IoT MQTT 為基礎的檔案傳送的錯誤

DescribeStreamGetStream 兩個 API 傳送至裝置的錯誤回應包含用戶端字符、錯誤碼及錯誤訊息。典型的錯誤回應看似下列範例所示。

{ "o": "BlockSizeOutOfBounds", "m": "The block size is out of bounds", "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380" }
  • "o" 為指出錯誤發生原因的錯誤代碼。如需詳細資訊,請參閱本節稍後的錯誤碼。

  • "m" 為包含錯誤詳細資料的錯誤訊息。

  • "c" 為用戶端字符欄位。若其提供於 DescribeStream 請求中,則可能會傳回。您可使用用戶端字符,使回應與其請求產生關聯。

    用戶端字符欄位不一定會包含在錯誤回應中。當提供於請求中的用戶端字符無效或格式錯誤時,其不會傳回錯誤回應。

注意

若為回溯相容性,錯誤回應中的欄位可能為非縮寫形式。例如,錯誤代碼可能由「代碼」或 "o" 欄位進行指定,用戶端字符欄位可由 "clientToken" 或 "c" 欄位進行指定。我們建議您使用上述縮寫形式。

InvalidTopic

串流訊息的 MQTT 主題是無效的。

InvalidJson

串流請求不是一個有效的 JSON 文件。

InvalidCbor

串流請求不是有效的 CBOR 文件。

InvalidRequest

該請求通常被標識為格式錯誤。如需詳細資訊,請參閱錯誤訊息。

未經授權

該請求無權存取儲存媒體 (例如 Amazon S3) 中的串流資料檔案。如需詳細資訊,請參閱錯誤訊息。

BlockSizeOutOfBounds

區塊大小超出範圍。請參閱 AWS IoT Core Service Quotas 中的「MQTT 型檔案交付」一節。

OffsetOutOfBounds

偏移超出範圍。請參閱 AWS IoT Core Service Quotas 中的「MQTT 型檔案交付」一節。

BlockCountLimitExceeded

請求區塊的數量超出範圍。請參閱 AWS IoT Core Service Quotas 中的「MQTT 型檔案交付」一節。

BlockBitmapLimitExceeded

請求點陣圖的大小超出範圍。請參閱 AWS IoT Core Service Quotas 中的「MQTT 型檔案交付」一節。

ResourceNotFound

找不到請求的串流、檔案、檔案版本或區塊。如需詳細資訊,請參閱錯誤訊息。

VersionMismatch

請求中的串流版本與 MQTT 型檔案交付功能中的串流版本不相符。這表示自裝置最初接收串流版本以來,串流資料已遭修改。

E TagMismatch

串流中的 S3 ETag 與最新 S3 物件版本的 ETag 不相符。

InternalError

於 MQTT 型檔案交付時發生內部錯誤。