本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用二进制负载
当将消息负载作为原始二进制数据(而不是 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)
有基本的了解 -
定义消息类型和相关依赖项的
.proto
文件 -
在您的系统上安装 Protobuf 编译器 (protoc)
创建描述符文件
如果您已有描述符文件,可以跳过此步骤。描述符文件 (.desc
) 是 .proto
文件的编译版本,它是一个文本文件,用于定义 protobuf 序列化中使用的数据结构和消息类型。要生成描述符文件,必须定义一个 .proto
文件,并使用 protoc
-
创建定义消息类型的
.proto
文件。示例.proto
文件可能如下所示:syntax = "proto3"; message Person { optional string name = 1; optional int32 id = 2; optional string email = 3; }
在此示例
.proto
文件中,使用 proto3 语法并定义消息类型Person
。Person
消息定义指定三个字段(名称、ID 和电子邮件)。有关.proto
文件消息格式的更多信息,请参阅语言指南 (proto3)。 -
使用 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 规则可以使用该文件来解码符合中定义的数据结构的 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 存储桶
创建描述符文件后,使用 AWS API <FILENAME>.desc
、S AWS DK 或,<FILENAME>.desc
将描述符文件上传到 Amazon S3 存储桶。 AWS Management Console
重要注意事项
-
请务必将描述符文件上传到您的 Amazon S3 存储桶,与您打算配置规则的 AWS 区域 位置相同。 AWS 账户
请确保您授予
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,但有以下限制:
最佳实践
以下是一些最佳实践和故障排查提示。
-
在 Amazon S3 存储桶中备份您的原型文件。
备份您的原型文件是一种很好的做法,以防出现问题。例如,如果您在运行 protoc 时错误地修改了没有备份的原型文件,这可能会导致您的生产堆栈出现问题。有多种方法可以在 Amazon S3 存储桶中备份您的文件。例如,您可以在 S3 存储桶中使用版本控制。有关如何备份 Amazon S3 存储桶中的文件的更多信息,请参阅 Amazon S3 开发人员指南。
-
配置 AWS IoT 日志以查看日志条目。
最好配置 AWS IoT 日志记录,这样你就可以在中查看账户的 AWS IoT 日志 CloudWatch。当规则的 SQL 查询调用外部函数时, AWS IoT Core Rules 会生成一个带为
eventType
的日志条目FunctionExecution
,其中包含可帮助您排除故障原因字段。可能的错误包括找不到 Amazon S3 对象,或者 protobuf 文件描述符无效。有关如何配置 AWS IoT 日志记录和查看日志条目的更多信息,请参阅配置 AWS IoT 日志记录和规则引擎日志条目。 -
使用新的对象键更新
FileDescriptorSet
,并更新规则中的对象键。您可以通过将更新后的描述符文件上传到 Amazon S3 桶来更新
FileDescriptorSet
。您对FileDescriptorSet
的更新最多需要 15 分钟能够反映出来。为了避免这一延迟,使用新的对象键上传更新后的FileDescriptorSet
,然后更新规则中的此对象密钥是一种很好的做法。