使用二進位承載 - AWS IoT Core

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

使用二進位承載

若要將訊息承載做為原始二進位資料 (而不是 JSON 物件) 處理,可以使用 * 運算子在 SELECT 子句中參考它。

二進位承載範例

使用 * 參考作為原始二進位資料的訊息承載時,您可以將資料新增至規則。如果您有空白或 JSON 承載,則產生的承載可以使用規則新增資料。下列顯示支援 SELECT 子句的範例。

  • 對於二進位承載,您可以使用下方僅具有一個 * 的 SELECT 子句。

    • SELECT * FROM 'topic/subtopic'
    • SELECT * FROM 'topic/subtopic' WHERE timestamp() % 12 = 0
  • 您也可以新增資料並使用下方 SELECT 子句。

    • SELECT *, principal() as principal, timestamp() as time FROM 'topic/subtopic'
    • SELECT encode(*, 'base64') AS data, timestamp() AS ts FROM 'topic/subtopic'
  • 您也可以使用這些 SELECT 子句搭配二進位承載使用。

    • 下方項目是指 WHERE 子句中的 device_type

      SELECT * FROM 'topic/subtopic' WHERE device_type = 'thermostat'
    • 也支援下方項目。

      { "sql": "SELECT * FROM 'topic/subtopic'", "actions": [ { "republish": { "topic": "device/${device_id}" } } ] }

下方規則動作不支援二進位承載,因此您必須將它們解碼。

  • 對於某些不支援二進位承載輸入 (例如 Lambda 動作) 的規則,您必須解碼二進位承載。如果 Lambda 規則動作是 base64 編碼且在 JSON 承載中,則可以接收二進位資料。您可以將規則變更如下,以此執行此項操作。

    SELECT encode(*, 'base64') AS data FROM 'my_topic'
  • SQL 陳述式不支援將字串作為輸入。若要將字串輸入轉換為 JSON,您可以執行下列命令。

    SELECT decode(encode(*, 'base64'), 'base64') AS payload FROM 'topic'

對 Protobuf 訊息承載進行解碼

協定緩衝區(protobuf)是一種開放原始碼資料格式,用於將結構化資料序列化為壓縮二進位形式。其可用於透過網路傳輸資料或將其儲存在檔案中。Protobuf 允許您以較小的數據包大小並以比其他消息傳遞格式更快的速度發送數據。 AWS IoT Core 規則通過提供解碼(值,解碼方案)SQL 函數來支持 protobuf,該函數允許您將原型編碼的消息有效載荷解碼為 JSON 格式並將其路由到下游服務。本節詳細介紹了在規則中配置原生解碼的 step-by-step AWS IoT Core 過程。

必要條件

建立描述項檔案

如果您已有描述項檔案,則可以略過此步驟。描述項檔案 (.desc) 是 .proto 檔案的編譯版本,屬於文字檔案,用於定義在 protobuf 序列化中使用的資料結構和訊息類型。要產生描述項檔案,您必須定義 .proto 檔案並使用 protoc 編譯器對其進行編譯。

  1. 建立用於定義訊息類型的 .proto 檔案。範例 .proto 檔案看起來可能與以下內容相似:

    syntax = "proto3"; message Person { optional string name = 1; optional int32 id = 2; optional string email = 3; }

    在此範例 .proto 檔案中,您使用 proto3 語法並定義訊息類型 PersonPerson 訊息定義會指定三個欄位 (名稱、ID 和電子郵件)。如需有關 .proto 檔案訊息格式的詳細資訊,請參閱 語言指南 (proto3)

  2. 使用 protoc 編譯器編譯 .proto 檔案並產生描述項檔案。用於建立描述項 (.desc) 檔案的範例命令如下所示:

    protoc --descriptor_set_out=<FILENAME>.desc \ --proto_path=<PATH_TO_IMPORTS_DIRECTORY> \ --include_imports \ <PROTO_FILENAME>.proto

    這個示例命令生成一個描述符文件<FILENAME>.desc, AWS IoT Core Rules 可以用它來解碼符合中定義的數據結構的 protobuf 有效載荷。<PROTO_FILENAME>.proto

    • --descriptor_set_out

      指定所要產生的描述項檔案 (<FILENAME>.desc) 名稱。

    • --proto_path

      指定編譯檔案所參考的任何已匯入 .proto 檔案的位置。如果您有多項已匯入的 .proto 檔案位於不同位置,則可以多次指定旗標。

    • --include_imports

      指定任何已匯入的 .proto 檔案也應加以編譯,並納入 <FILENAME>.desc 描述項檔案中。

    • <PROTO_FILENAME>.proto

      指定要編譯的 .proto 檔案名稱。

    如需 protoc 參考的詳細資訊,請參閱 API 參考

將描述項檔案上傳至 S3 儲存貯體

建立描述元檔案後<FILENAME>.desc<FILENAME>.desc請使用 AWS API、 AWS 開發套件或 AWS Management Console.

重要考量

  • 請確定您將描述元檔案上傳到您想要設定規則 AWS 帳戶 的相同 AWS 區域 位置的 Amazon S3 儲存貯體。

  • 確保您授予FileDescriptorSet從 S3 讀 AWS IoT Core 取的訪問權限。如果 S3 儲存貯體已停用伺服器端的加密 (SSE),或者 S3 儲存貯體是使用 Amazon S3 受管金鑰 (SSE-S3) 進行加密,則不需要其他政策組態。下列範例儲存貯體政策可實現此目的:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "s3:Get*", "Resource": "arn:aws:s3:::<BUCKET NAME>/<FILENAME>.desc" } ] }
  • 如果您的 S3 儲存貯體使用金 AWS Key Management Service 鑰 (SSE-KMS) 加密,請確保在存取 S3 儲存貯體時授 AWS IoT Core 予使用金鑰的權限。作法為您可以將下列陳述式新增至金鑰政策:

    { "Sid": "Statement1", "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" }

在規則中設定 protobuf 解碼

將描述項檔案上傳到 Amazon S3 儲存貯體後,請設定一項規則以供使用 decode(value, decodingScheme) SQL 函數來解碼 protobuf 訊息承載格式。詳細的函數簽章和範例可參見 AWS IoT SQL 參考decode(value, decodingScheme) SQL 函數。

以下是使用 decode(value, decodingScheme) 函數的 SQL 表達式範例:

SELECT VALUE decode(*, 'proto', '<BUCKET NAME>', '<FILENAME>.desc', '<PROTO_FILENAME>', '<PROTO_MESSAGE_TYPE>') FROM '<MY_TOPIC>'

在此範例表達式中:

  • 您可以使用 decode(value, decodingScheme) SQL 函數,來解碼 * 參考的二進位訊息承載。這可以是二進位 protobuf 編碼承載,也可以是代表 base64 編碼 protobuf 承載的 JSON 字串。

  • 所提供的訊息承載會使用 PROTO_FILENAME.proto 中定義的Person 訊息類型進行編碼。

  • 名為 BUCKET NAME 的 Amazon S3 儲存貯體含有從 PROTO_FILENAME.proto 產生的 FILENAME.desc

完成設定後,請針對訂閱規則 AWS IoT Core 的主題發佈訊息至。

限制

AWS IoT Core 規則支援原生成,但有下列限制:

  • 不支援在替代範本中解碼 protobuf 訊息承載。

  • 在解碼 protobuf 訊息承載時,您最多可以在單一 SQL 表達式中使用解碼 SQL 函數 2 次。

  • 傳入承載大小上限為 128 KiB (1KiB = 1024 位元組),傳出承載大小上限為 128 KiB,而儲存在 Amazon S3 儲存貯體中的 FileDescriptorSet 物件大小上限為 32 KiB。

  • 不支援使用 SSE-C 加密功能對 Amazon S3 儲存貯體進行加密。

最佳實務

以下是一些最佳實務和疑難排解提示。

  • 在 Amazon S3 儲存貯體中備份原型檔案。

    理想的做法是備份 proto 檔案以防患未然。例如,如果在執行 protoc 時錯誤地修改了沒有備份的原型檔案,這可能會導致生產堆疊發生問題。有多種方法在 Amazon S3 儲存貯體中備份檔案 例如,您可以在 S3 儲存貯體中使用版本控制。如需有關如何備份 Amazon S3 儲存貯體中檔案的詳細資訊,請參閱 Amazon S3 開發人員指南

  • 設定 AWS IoT 記錄以檢視記錄項目。

    配置日誌 AWS IoT 記錄是一個很好的做法,以便您可以在中檢查帳戶的 AWS IoT 日誌 CloudWatch。當規則的 SQL 查詢呼叫外部函數時,Ru AWS IoT Core les 會產生一個eventType記錄項目FunctionExecution,其中包含可協助您疑難排解失敗問題的 reason 欄位。可能的錯誤包括找不到 Amazon S3 物件,或是 protobuf 檔案描述項無效。如需進一步了解如何設定 AWS IoT 記錄及查看日誌項目,請參閱設定 AWS IoT 記錄規則引擎日誌項目

  • 使用新的物件索引鍵來更新 FileDescriptorSet 以及更新規則中的物件索引鍵。

    您可以將更新後的描述項檔案上傳到 Amazon S3 儲存貯體來更新 FileDescriptorSet。系統可能需要最多 15 分鐘的時間來反映 FileDescriptorSet 的更新作業。為了避免這種延遲,理想做法是使用新的物件索引鍵上傳更新後的 FileDescriptorSet,並在規則中更新物件索引鍵。