使用AWS IoT设备中基于 MQTT 的文件传输 - AWS IoT Core

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用AWS IoT设备中基于 MQTT 的文件传输

要启动数据传输过程,设备必须接收初始数据集,其中至少包含一个流 ID。您可以使用Jobs通过在作业文档中包含初始数据集来计划设备的数据传输任务。当设备收到初始数据集时,它应该开始与AWS IoT基于 MQTT 的文件传输。若要与AWS IoT基于 MQTT 的文件传输,设备应:

您可以选择在初始数据集中包含流文件 ID 和流版本。将流文件 ID 发送到设备可以简化设备的固件/软件的编程,因为它不需要使DescribeStream请求以获取此 ID。设备可以在GetStream请求强制执行一致性检查,以防流意外更新。

使用 DescribeStream 获取流数据

AWS IoT基于 MQTT 的文件传输提供DescribeStreamAPI 将流数据发送到设备。此 API 返回的流数据包括流 ID、流版本、流描述和流文件列表,每个流文件都有一个文件 ID 和文件大小(以字节为单位)。通过这些信息,设备可以选择任意文件来启动数据传输过程。

注意

您无需使用DescribeStreamAPI(如果您的设备在初始数据集中收到所有必需的流文件 ID)。

按照以下步骤进行DescribeStream请求.

  1. 订阅 “已接受” 主题过滤器$aws/things/ThingName/streams/StreamId/description/json

  2. 订阅 “拒绝” 主题过滤器$aws/things/ThingName/streams/StreamId/rejected/json

  3. 发布DescribeStream请求,通过向$aws/things/ThingName/streams/StreamId/describe/json

  4. 如果请求被接受,您的设备会收到DescribeStream响应 “已接受” 主题过滤器。

  5. 如果请求被拒绝,您的设备会收到 “已拒绝” 主题筛选器上的错误响应。

注意

如果将json替换为cbor在显示的主题和主题过滤器中,您的设备会接收 CBOR 格式的消息,这比 JSON 更紧凑。

DescribeStream 请求

典型的DescribeStream请求类似于以下示例。

{ "c": "ec944cfb-1e3c-49ac-97de-9dc4aaad0039" }
  • (可选)”c” 是客户端令牌字段。

    客户端令牌不能超过 64 字节。超过 64 字节的客户端令牌将导致错误响应和InvalidRequest错误消息。

DescribeStream 响应

ADescribeStream响应类似于以下示例。

{ "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” 包含流的描述。

从流文件中获取数据块

您可以使用GetStreamAPI,以便设备可以接收小数据块中的流文件,因此可以由那些对处理大块大小有限制的设备使用。要接收整个数据文件,设备可能需要发送或接收多个请求和响应,直到接收和处理所有数据块。

获取流请求

执行以下步骤以创建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 的多个块发出请求(例如,如果您请求 5 个块(32 KB),每个块共有 160 KB 的数据)。在这种情况下,请求不会失败,但您的设备必须发出多个请求才能接收请求的所有数据。当您的设备提出额外请求时,该服务将发送额外的数据块。我们建议您仅在正确接收和处理之前的响应之后继续执行新的请求。

  • 无论请求的数据总大小如何,您都应该对设备进行编程,以便在未收到数据块或未正确接收数据块时启动重试。

典型的GetStream请求类似于以下示例。

{ "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380", "s": 1, "f": 0, "l": 4098, "o": 2, "n": 100, "b": "..." }
  • [可选]”c” 是客户端令牌字段。

    客户端令牌不能超过 64 字节。超过 64 字节的客户端令牌将导致错误响应和InvalidRequest错误消息。

  • [可选]”s” 是流版本字段(整数)。

    基于 MQTT 的文件传输应用基于此请求的版本和云中的最新流版本的一致性检查。如果从设备发送的流版本GetStream请求与云中的最新流版本不匹配,则服务会发送错误响应,并且VersionMismatch错误消息。通常,设备会在初始数据集或响应中接收预期(最新)的流版本DescribeStream

  • "f” 是流文件 ID(范围为 0 到 255 的整数)。

    创建或更新流时,需要使用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/数据块大小

  • [可选]”b” 是一个位图,表示正在请求的块。

    使用位图,您的设备可以请求非连续的块,这使得处理错误后的重试更加方便。请参阅为 GetStream 请求构建位图,了解有关如何使用位图字段指定流文件的哪一部分将在GetStream响应. 对于此字段,将位图转换为以十六进制表示位图值的字符串。位图必须小于 12,288 个字节。

GetStream 响应

AGetStream响应对于每个请求的数据块来说都像这个示例一样。

{ "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380", "f": 0, "l": 4098, "i": 2, "p": "..." }
  • "c” 是客户端令牌字段。这将返回,如果它是在GetStream请求. 使用客户端令牌将响应与其请求相关联。

  • "f” 是当前数据块负载所属的流文件的 ID。

  • "l” 是数据块有效负载的大小(以字节为单位)。

  • "i” 是负载中包含的数据块的 ID。数据块从 0 开始编号。

  • "p” 包含数据块有效负载。此字段是一个字符串,用十六进制表示法表示数据块的值。

为 GetStream 请求构建位图

您可以使用位图字段 (b) 中的GetStream请求从流文件中获取非连续块。这有助于 RAM 容量有限的设备处理网络交付问题。设备只能请求那些未接收或未正确接收的块。位图确定将返回流文件的哪些块。对于位图中设置为 1 的每个位,将返回相应的流文件块。

下面的示例演示如何在GetStream请求. 例如,您希望以 256 字节的块(块大小)接收流文件。将每个 256 字节的块视为有一个指定其在文件中位置的数字,从 0 开始。所以块 0 是文件中 256 字节的第一个块,块 1 是第二个块,依此类推。您想要从文件中请求块 20、21、24 和 43。

块偏移量

由于第一个块是数字 20,因此指定偏移量(字段o)设置为 20,以节省位图中的空间。

块数

为了确保您的设备收到的块数不会超过其在有限内存资源中所能处理的数量,您可以指定基于 MQTT 的文件传输发送的每条消息中应返回的最大块数。请注意,如果位图本身指定的块数小于此数,或者如果它会使基于 MQTT 的文件传输发送的响应消息的总大小大于每个 128 KB 的服务限制,则忽略此值GetStream请求.

块储存位图

位图本身是一个以十六进制表示法表示的无符号字节数组,并包含在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”,“0 亿万” 和 “0b1000 万”。位 0 显示在第一个字节末尾的二进制表示中,位 23 显示在最后一个字节的开头。除非你知道约定,否则这可能会令人困惑。第一个字节包含位 7-0(按该顺序),第二个字节包含位 15-8,第三个字节包含位 23-16,依此类推。在十六进制表示法中,这将转换为 “0x130080”。

提示

您可以将标准二进制转换为十六进制表示法。一次取四个二进制数字,并将它们转换为十六进制等效数字。例如,“0001” 变为 “1",“0011” 变成 “3”,依此类推。

将这一切结合起来,我们的GetStream请求类似于以下内容。

{ "c" : "1", // client token "s" : 1, // expected stream version "l" : 256, // block size "f" : 1, // source file index id "o" : 20, // block offset "n" : 32, // number of blocks "b" : "0x130080" // A missing blockId bitmap starting from the offset }

处理来自的错误AWS IoT基于 MQTT 的文件传输

发送到设备的错误响应DescribeStreamGetStreamAPI 包含客户端令牌、错误代码和错误消息。典型的错误响应类似于以下示例。

{ "o": "BlockSizeOutOfBounds", "m": "The block size is out of bounds", "c": "1bb8aaa1-5c18-4d21-80c2-0b44fee10380" }
  • "o” 是指示出现错误原因的错误代码。有关更多详细信息,请参阅本节后面的错误代码。

  • "m” 是包含错误详细信息的错误消息。

  • "c” 是客户端令牌字段。这可能会返回,如果它是在DescribeStream请求. 您可以使用客户端令牌将响应与其请求相关联。

    客户端令牌字段并不总是包含在错误响应中。当请求中给出的客户端令牌无效或格式不正确时,它不会在错误响应中返回。

注意

为了向后兼容,错误响应中的字段可能采用非缩写形式。例如,错误代码可能由 “代码” 或 “o” 字段指定,clientToken 字段可以由 “ClientToken” 或 “c” 字段指定。建议您使用以上显示的缩写形式。

InvalidTopic

流消息的 MQTT 主题无效。

InvalidJson

流请求不是有效的 JSON 文档。

无效

流请求无效。

InvalidRequest

请求通常被标识为格式错误。有关详细信息,请参阅错误消息。

未授权

未授权请求访问存储介质(如 Amazon S3)中的流数据文件。有关详细信息,请参阅错误消息。

块大小超出边界

块大小超出界限。请参阅”基于 MQTT 的文件传输中的部分 AWS IoT Core Service Quotas

偏移边界

偏移超出界限。请参阅”基于 MQTT 的文件传输中的部分 AWS IoT Core Service Quotas

块数限制

请求块的数量超出了界限。请参阅”基于 MQTT 的文件传输中的部分 AWS IoT Core Service Quotas

区块位图限制

请求位图的大小超出了界限。请参阅”基于 MQTT 的文件传输中的部分 AWS IoT Core Service Quotas

ResourceNotFound

找不到请求的流、文件、文件版本或块。有关更多详细信息,请参阅错误消息。

VersionMismatch

请求中的流版本与基于 MQTT 的文件传输功能中的流版本不匹配。这表示自设备最初接收流版本以来,流数据已被修改。

信息不匹配

流中的 S3 ETag 与最新 S3 对象版本的 ETag 不匹配。

InternalError

基于 MQTT 的文件传输中发生内部错误。