MQTT - Amazon IoT Core
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

MQTT

MQTT(消息队列遥测传输)是一种广泛采用的轻型消息传递协议,专为受限制的设备而设计。Amazon IoT Core 对 MQTT 的支持基于 MQTT v3.1.1 规范MQTT v5.0 规范,但如 Amazon IoT 与 MQTT 规范不同 中所述,有一些差异。作为此标准的最新版本,MQTT 5 引入了多项使基于 MQTT 的系统更强大的关键特征,包括新的可扩展性增强、通过原因代码响应改进的错误报告、消息和会话到期计时器,以及自定义用户消息标头。有关 Amazon IoT Core 支持的 MQTT 5 特征的更多信息,请参阅 MQTT 5 支持的特征。Amazon IoT Core 还支持跨 MQTT 版本(MQTT 3 和 MQTT 5)通信。MQTT 3 发布者可以向将接收 MQTT 5 发布消息的 MQTT 5 订阅者发送 MQTT 3 消息,反之亦然。

Amazon IoT Core 支持使用 MQTT 协议和 MQTT WSS 协议上并由客户端 ID 标识的设备连接。Amazon IoT Device SDK 支持这两种协议,并且是将设备连接到 Amazon IoT Core 的推荐方法。Amazon IoT 设备 SDK 支持设备和客户端连接和访问 Amazon IoT 服务所需的功能。设备 SDK 支持 Amazon IoT 服务所需的身份验证协议以及 MQTT 协议和 MQTT over WSS 协议所需的连接 ID 要求。有关如何使用 Amazon IoT Device SDK 连接到 Amazon 的信息以及指向受支持语言形式的 Amazon IoT 示例的链接,请参阅 使用 Amazon IoT Device SDK 与 MQTT 连接。有关 MQTT 消息的身份验证方法和端口映射的更多信息,请参阅协议、端口映射和身份验证

虽然我们建议使用 Amazon IoT Device SDK 连接到 Amazon IoT,但它们并不是必需的。但是,如果您不使用 Amazon IoT Device SDK,则必须提供必要的连接和通信安全性。客户端必须在连接请求中发送服务器名称指示 (SNI) TLS 扩展。不包括 SNI 的连接尝试将被拒绝。有关更多信息,请参阅 Amazon IoT 中的传输安全。使用 IAM 用户和Amazon凭证对客户端进行身份验证的客户端必须提供正确的 Signature Version 4 身份验证。

使用 Amazon IoT Device SDK 与 MQTT 连接

本节包含指向 Amazon IoT Device SDK 以及演示如何将设备连接到 Amazon IoT 的示例程序源代码的链接。此处链接的示例应用程序演示如何使用 MQTT 协议和基于 WSS 的 MQTT 协议连接到 Amazon IoT。

注意

Amazon IoT 设备 SDK 已在开发者预览版中发布了 MQTT 5 客户端。在预览期间,我们可能会对公共 API 进行向后不兼容的更改,Amazon IoT 设备 SDK 中的服务客户端将继续使用 MQTT 3.1.1 客户端。

C++

使用 Amazon IoT C++ 设备 SDK 连接设备

Python

使用适用于 Python 的 Amazon IoT 设备 SDK 连接设备

JavaScript

使用适用于 JavaScript 的 Amazon IoT 设备 SDK 连接设备

Java

使用适用于 Java 的 Amazon IoT 设备 SDK 连接设备

Embedded C

使用适用于嵌入式 C 的 Amazon IoT 设备 SDK 连接设备

重要

该 SDK 供经验丰富的嵌入式软件开发人员使用。

MQTT 服务质量 (QoS) 选项

Amazon IoT 和 Amazon IoT Device SDK 支持 MQTT 服务质量 (QoS) 级别 01。MQTT 协议定义了第三级 QoS(即级别 2),但 Amazon IoT 不支持它。只有 MQTT 协议支持 QoS 特征。HTTPS 通过传递查询字符串参数 ?qos=qos 来支持 QoS,其值可以是 0 或 1。

下表描述了每个 QoS 级别如何影响发布到消息代理和由消息代理发布的消息。

QoS 级别为...

消息为...

注释

QoS 级别 0

不发送或发送多次

此级别应该用于通过可靠通信链接发送的消息,或者可以毫无问题地错过的消息。

QoS 级别 1

至少发送一次,然后重复发送,直到收到 PUBACK 响应

在发送方收到指示成功传递的 PUBACK 响应之前,该消息不被认为是完整的。

MQTT 持久性会话

持久性会话存储客户端尚未确认的服务质量(QoS)为 1 的客户端的订阅和消息。当设备重新连接到持久性会话时,该会话恢复,订阅恢复,并将在重新连接之前接收和存储的未确认的订阅消息发送到客户端。

存储消息的处理记录在 CloudWatch 和 CloudWatch Logs 中。有关向 CloudWatch 和 CloudWatch Logs 写入的条目的信息,请参阅消息代理指标排队的日志条目

创建持久性会话

在 MQTT 3 中,您可以通过发送 CONNECT 消息并将 cleanSession 标记设置为 0 来创建 MQTT 持久性会话。如果发送 CONNECT 消息的客户端不存在会话,则会创建一个新的持久性会话。如果客户端已存在会话,则客户端会恢复现有会话。要创建干净会话,您需要发送一条 CONNECT 消息,并将 cleanSession 标志设置为 1,当客户端断开连接时,代理将不存储任何会话状态。

在 MQTT 5 中,您可以通过设置 Clean Start 标志和 Session Expiry Interval 来处理永久性会话。干净启动控制连接会话的开始和上一会话的结束。当您设置 Clean Start = 1 时,会创建一个新会话,如果之前的会话存在,将终止之前的会话。当您设置 Clean Start = 0 时,连接会话将恢复之前的会话(如果存在之前的会话)。会话过期间隔控制连接会话的结束。会话过期间隔指定断开连接后会话将持续的时间(以秒为单位,4 字节整数)。设置 Session Expiry interval=0 可使会话在断开连接后立即终止。如果未在 CONNECT 消息中指定会话过期间隔,默认值为 0。

MQTT 5 干净启动和会话过期
属性值 描述
Clean Start= 1 创建新会话并终止之前的会话(如果存在之前的会话)。
Clean Start= 0 如果存在之前的会话,则恢复会话。
Session Expiry Interval> 0 持续会话。
Session Expiry interval= 0 不持续会话。

在 MQTT 5 中,如果设置 Clean Start = 1Session Expiry Interval = 0,这相当于 MQTT 3 清理会话。如果设置 Clean Start = 0Session Expiry Interval > 0,这相当于 MQTT 3 永久会话。

注意

不支持跨 MQTT 版本(MQTT 3 和 MQTT 5)的持久性会话。无法将 MQTT 3 持久性会话恢复为 MQTT 5 会话,反之亦然。

持久性会话期间的操作

客户端使用连接已确认 (CONNACK) 消息中的 sessionPresent 属性确定是否存在持久性会话。如果 sessionPresent1,则存在持久性会话,并且在客户端收到 CONNACK 后将为客户端存储的所有消息传送给客户端,如重新连接到持久性会话后的消息流量中所述。如果 sessionPresent1,则客户端无需重新订阅。但是,如果 sessionPresent0,则不存在持久性会话,并且客户端必须重新订阅主题筛选条件。

客户端加入持久性会话后,它可以发布消息并订阅主题筛选条件,而无需在每个操作上附加任何标记。

重新连接到持久性会话后的消息流量

持久性会话表示客户端与 MQTT 消息代理之间的持续连接。当客户端使用持久性会话连接到消息代理时,消息代理会保存客户端在连接期间所做的所有订阅。当客户端断开连接时,消息代理将未确认的 QoS 1 消息和发布的新 QoS 1 消息存储到客户端订阅的主题。根据账户限制存储消息。超过限制的消息将被删除。有关持久消息限制的更多信息,请参阅 Amazon IoT Core 终端节点和配额。当客户端重新连接到其持久性会话时,将恢复所有订阅,并以每秒 10 条消息的最大速率将所有已存储消息发送到客户端。在 MQTT 5 中,如果具有消息过期间隔的出站 QoS1 在客户端离线时过期,则连接恢复后,客户端将不会收到过期消息。

重新连接后,以每秒限制为 10 条已存储消息的速率将已存储消息与任何当前消息流量一起发送到客户端,直到达到 Publish requests per second per connection 限制。由于已存储消息的传递速率受到限制,如果会话在重新连接后有超过 10 条已存储消息要传递,传递所有已存储的消息将需要几秒钟的时间。

结束持久性会话

持久性会话可通过以下方式结束:

  • 持久性会话到期时间已过。当消息代理检测到客户端已断开连接(通过客户端断开连接或连接超时)时,持久性会话到期计时器将启动。

  • 客户端发送将 cleanSession 标记设置为 1CONNECT 消息。

在 MQTT 3 中,持久性会话过期时间的默认值为一小时,此设置适用于账户中的所有会话。

在 MQTT 5 中,您可以为 CONNECT 和 DISCONNECT 数据包上的每个会话设置会话过期间隔。

对于 DISCONNECT 数据包上的会话过期间隔:

  • 如果当前会话的会话过期间隔为 0,则无法在 DISCONNECT 数据包上将会话过期间隔设置为大于 0。

  • 如果当前会话的会话过期间隔大于 0,并且您在 DISCONNECT 数据包上将会话过期间隔设置为 0,会话将在 DISCONNECT 上结束。

  • 否则,DISCONNECT 数据包的会话过期间隔将更新当前会话的会话过期间隔。

注意

会话结束时等待发送给客户端的已存储消息将被丢弃;但是,即使无法发送,也仍按标准消息传递费率计费。有关消息定价的更多信息,请参阅 Amazon IoT Core 定价。您可以配置到期时间间隔。

持久性会话到期后重新连接

如果客户端在其持久性会话到期之前未重新连接到该会话,则该会话结束并丢弃其存储的消息。当客户端在会话到期后重新连接并将 cleanSession 标记设置为 0 时,服务会创建一个新的持久性会话。上一个会话中的任何订阅或消息都不可用于此会话,因为它们在上一个会话到期时被丢弃。

持久性会话消息费用

当消息代理向客户端或离线永久性会话发送消息时,消息将向您的Amazon Web Services 账户收费。当具有持久会话的离线设备重新连接并恢复其会话时,存储的消息将传递到设备并再次向您的账户收费。有关消息定价的更多信息,请参阅 Amazon IoT Core 定价 - 消息收发

通过使用标准限制增加过程,可以将默认的持久性会话到期时间延长 1 小时。请注意,增加会话过期时间可能会增加消息费用,因为额外的时间可能允许离线设备存储更多消息,而这些额外的消息费用将按标准消息收发费率计入您的账户。会话到期时间为大约时间,会话的持续时间最多可能比账户限制长 30 分钟;但是,会话时间不会短于账户限制。有关会话限制的更多信息,请参阅 Amazon Service Quotas

MQTT 保留消息

Amazon IoT Core 支持 MQTT 协议中描述的 RETAIN 标志。当客户端在发布的 MQTT 消息上设置 RETAIN 标志时,Amazon IoT Core 保存该消息。然后可以将其发送给新的订阅者,通过调用 GetRetainedMessage 操作进行检索,并在 Amazon IoT 控制台中查看。

使用 MQTT 保留消息的示例
  • 作为初始配置消息

    客户端订阅主题后,MQTT 保留消息会被发送给客户端。如果希望订阅主题的所有客户端在订阅后立即接收 MQTT 保留消息,您可以发布设置了RETAIN 标志的配置消息。只要发布新的配置消息,订阅客户端也会收到该配置更新。

  • 作为最后一个已知的状态消息

    设备可以在当前状态消息上设置 REATIN 标志,以便 Amazon IoT Core 保存它们。当应用程序连接或重新连接时,它们可以订阅此主题并在订阅保留消息主题后立即获得上一次报告状态。这样,它们就不必等到设备发出下一条消息才能看到当前状态。

将 MQTT 保留消息存储在 Amazon IoT Core 中的常见任务

Amazon IoT Core 使用 RETAIN 标志设置保存 MQTT 消息。这些 保留消息 被作为普通的 MQTT 消息发送给已订阅该主题的所有客户端,同时也被存储起来发送给该主题的新订阅者。

客户端需要特定的策略操作授权才能访问 MQTT 保留消息。获取有关使用保留消息策略的示例,请参阅 保留的消息策略示例

本节介绍了涉及保留消息的常见操作。

  • 创建保留消息

    客户端在发布 MQTT 消息时确定是否保留消息。客户端可以在发布消息时使用 设备 SDK 设置 RETAIN 标志。应用程序和服务可以在使用 Publish 操作 发布 MQTT 消息时设置 RETAIN 标志。

    每个主题名称只保留一条消息。发布到主题的带有 RETAIN 标志设置的新消息将替换先前发送到该主题的任何现有保留消息。

    注意: 如果您设置了 RETAIN 标志则不能发布到 预留主题

  • 订阅保留消息主题

    客户端订阅保留消息主题,就像订阅任何其他 MQTT 消息主题一样。通过订阅保留消息主题接收的保留消息均有 RETAIN 标志设置。

    当客户端将具有 0 字节消息负载的保留消息发布到保留消息主题时,将从 Amazon IoT Core 中删除保留消息。已订阅保留消息主题的客户端也将收到该 0 字节消息。

    订阅包含保留消息主题的通配符主题筛选条件可使客户端接收发布到保留消息主题的后续消息,但在订阅时不会传递保留消息。

    注意: 要在订阅时接收保留消息,订阅请求中的主题筛选条件必须与保留消息主题完全匹配。

    订阅保留消息主题时收到的保留消息有 RETAIN 标志设置。订阅客户端在订阅后收到的保留消息则没有。

  • 检索保留消息

    当客户端使用保留消息订阅主题时,保留消息会被自动发送给客户端。要让客户端在订阅时收到保留消息,必须订阅保留消息的确切主题名称。通过订阅包含保留消息主题的通配符主题筛选条件,客户端可以接收发布到保留消息主题的后续消息,但不会在订阅时传送保留消息。

    服务和应用可以通过调用 ListRetainedMessagesGetRetainedMessage 列出和检索保留消息。

    设置 RETAIN 标志的情况下,客户端不会被阻止发布消息到保留消息主题。这可能会导致意外结果,例如保留消息与订阅主题收到的消息不匹配。

    在 MQTT 5 中,如果保留消息设置了消息过期间隔且保留消息已过期,则订阅该主题的新订阅者在成功订阅后将不会收到该保留消息。

  • 列出保留消息主题

    您可以通过调用 ListRetainedMessages 列出保留消息,并且可以在 Amazon IoT 控制台 中查看保留消息。

  • 获取保留消息详细信息

    您可以通过调用 GetRetainedMessage 获取保留消息的详细信息,并且可以在 Amazon IoT 控制台 中查看这些信息。

  • 保留 Will 消息

    连接设备时创建的 MQTT Will 消息 可以通过设置 Connect Flag bits 字段中的 Will Retain 标记保留。

  • 删除保留消息

    通过将设置了 RETAIN 标志的消息和空(0字节)消息负载发布到要删除的保留消息的主题名称,设备、应用程序和服务可以删除保留消息。从 Amazon IoT Core 中删除保留消息的此类消息被发送给订阅了该主题的客户端,但 Amazon IoT Core 不会保留此类消息。

    还可以通过访问 Amazon IoT 控制台 中的保留消息以交互的方式删除保留消息。通过 Amazon IoT 控制台 删除的保留消息也会向已订阅保留消息主题的客户端发送 0 字节的消息。

    保留消息在删除后无法恢复。客户端需要发布新的保留消息才能取代已删除的消息。

  • 保留消息的调试和故障排查

    Amazon IoT 控制台 提供多个工具来帮助您进行保留消息故障排查:

    • 保留消息 页面

      Amazon IoT 控制台中的 保留消息 页面提供您的账户在当前区域中存储的保留消息的分页列表。在此页面上,您可以:

      • 查看每条保留消息的详细信息,例如消息负载、QoS、接收时间。

      • 更新保留消息的内容。

      • 删除保留消息。

    • 打开 MQTT 测试客户端

      Amazon IoT 控制台中的 MQTT 测试客户端 页面可以订阅并发布到 MQTT 主题。发布选项让您可以在发布的消息上设置 REATEIN 标志,以模拟设备的行为方式。

    在 Amazon IoT Core 中如何应用保留消息的这些方面可能会产生一些意外的结果。

    • 保留消息限制

      当帐户存储了最大数量的保留消息时,对于使用 RETAIN 设置且有效负载大于 0 字节的发布消息,Amazon IoT Core 将返回限制响应,直到一些保留消息被删除且保留消息数量低于限制。

    • 保留消息传递顺序

      不保证保留消息和订阅消息传递的顺序。

账单和保留消息

从客户端通过使用 Amazon IoT 控制台或调用 Publish 发布设置了 RETAIN 标志的消息会产生 Amazon IoT Core 定价-消息收发 中说明的额外消息收发费用。

除了正常的 API 使用费之外,通过客户端、使用 Amazon IoT 控制台或调用 GetRetainedMessage 检索保留消息还会产生消息收发费用。Amazon IoT Core 定价-消息收发 中说明了此类额外费用。

在设备意外断开连接时发布的 MQTT Will消息 会产生 Amazon IoT Core 定价-消息收发 中说明的消息收发费用。

有关消息传递定价的更多信息,请参阅 Amazon IoT Core 定价 - 消息传递

比较 MQTT 保留消息和 MQTT 持久会话

保留消息和持久性会话是 MQTT 的标准特征,使设备能够接收离线时发布的消息。持久会话中可以发布保留消息。本节介绍这些特征的主要方面及其如何协作。

保留消息

持久会话

主要特征

在连接大量设备后,保留消息可用于配置或通知这些设备。

如果您希望设备仅接收重新连接后发布到主题的最后一条消息,也可以使用保留消息。

持久会话对于间歇性连接而可能错过多条重要消息的设备非常有用。

设备可以连接持久会话来接收离线时发送的消息。

示例

保留消息可以在设备上线时提供有关其环境的配置信息。初始配置可以包括应该订阅的其他消息主题的列表,或者如何配置本地时区的相关信息。

通过间歇连接的蜂窝网络连接的设备可以使用持久会话,避免丢失在设备超出网络覆盖范围或需要关闭其蜂窝无线电时发送的重要消息。

初始订阅主题时收到的消息

订阅带有保留消息的主题后,会收到最近的保留消息。

在订阅没有保留消息的主题后,向该主题发布消息之前不会收到任何消息。

重新连接后订阅的主题

如果没有持久会话,客户端必须在重新连接后订阅主题。

重新连接后,将恢复订阅的主题。

重新连接后收到的消息

订阅带有保留消息的主题后,会收到最近的保留消息。

在设备断开连接时,所有以 QOS = 1 发布并使用 QOS =1 订阅的消息都将在设备重新连接后发送。

数据会话过期

在 MQTT 3 中,保留消息不会过期。它们将被存储,直至被替换或删除。在 MQTT 5 中,保留消息会在您设置的消息过期间隔后过期。有关更多信息,请参阅消息过期

如果未在超时期限内重新连接客户端,持久会话将过期。持久会话过期后,在设备断开连接时以 QOS = 1 发布并使用 QOS =1 订阅的客户端订阅和保存消息将被删除。将不会传送已过期的消息。获取有关持久会话的会话过期时间的更多信息,请参阅 MQTT 持久性会话

有关持久性存储的信息,请参阅 MQTT 持久性会话

使用保留消息,发布客户端可确定是否应在连接后保留消息并将其传送到设备,是否有上一个会话。是否存储消息由发布者自行选择,存储的消息将被发送给所有使用 QoS 0 或 QoS 1 订阅的当前和未来客户端。保留消息一次只保存一条给定主题的消息。

当帐户存储了最大数量的保留消息时,Amazon IoT Core 将对使用 RETAIN 集和大于 0 字节的有效负载发布的消息返回限制响应,直到删除一些保留消息且保留消息数不超过限制。

MQTT 保留了消息和 Amazon IoT Device Shadows

保留消息和 Device Shadows 都保留来自设备的数据,但它们的行为不同,用途也不同。本节介绍它们的相似之处和不同之处。

保留消息

设备影子

消息有效负载具有预定义的结构或架构

正如实施所定义的。MQTT 没有为其消息负载指定结构或架构。

Amazon IoT 支持特定的数据结构。

更新消息负载会生成事件消息

发布保留消息会将消息发送到订阅的客户端,但不会生成其他更新消息。

更新 Device Shadow会出现更新描述更改的消息

消息更新已编号

保留消息不会自动编号。 Device Shadow 文档具有自动版本号和时间戳。

消息有效负载附加到事物资源上

保留消息不会附加到事物资源。

Device Shadows 附加到事物资源。

更新消息有效负载的单个元素

如果不更新整个消息负载,就无法更改消息的单个元素。

可以更新 Device Shadow 文档的各个元素,而无需更新整个 Device Shadow 文档。

客户端在订阅时收到消息数据

在订阅带保留消息的主题后,客户端会自动收到保留消息。

客户端可以订阅 Device Shadow 更新,但他们必须故意请求当前状态。

索引和可搜索性

保留消息不会编制索引进行搜索。

实例集索引 Device Shadow 数据进行搜索和聚合。

MQTT Last Will and Testament(LWT)消息

Last Will and Testament(LWT)是 MQTT 中的一项特征。借助 LWT,客户端可以指定一条消息,当出现未启动的断开连接时,代理将该消息发布到客户定义的主题,并发送给订阅该主题的所有客户端。客户端指定的消息称为 LWT 消息或 Will 消息,客户端定义的主题称为 Will 主题。您可以指定当设备连接到代理时的 LWT 消息。通过在连接期间在 Connect Flag bits 字段中设置 Will Retain 标志,可以保留这些消息。例如,如果 Will Retain 标志设置为 1,则 Will 消息将存储在代理中的关联 Will 主题中。有关更多信息,请参阅 Will 消息

代理将存储 Will 消息,直到出现未启动的断开连接。发生这种情况时,代理将向所有订阅 Will 主题的客户端发布消息以通知断开连接。如果客户端使用 MQTT DISCONNECT 消息通过客户端启动的断开连接来断开与代理的连接,则代理不会发布存储的 LWT 消息。在所有其它情况下,将分派 LWT 消息。有关代理发送 LWT 消息时的断开连接场景的完整列表,请参阅连接/断开连接事件

使用 ConnectAttributes

ConnectAttributes 允许您在 IAM policy 中指定要在连接消息中使用的属性,如 PersistentConnectLastWill。借助 ConnectAttributes,您可以构建默认情况下不允许设备访问新特征的策略,这在设备受到威胁时很有帮助。

connectAttributes 支持以下特征:

PersistentConnect

当客户端和代理之间的连接中断时,使用 PersistentConnect 特征可以保存客户端在连接期间所做的所有订阅。

LastWill

当客户端意外断开连接时,使用 LastWill 特征可以向 LastWillTopic 发布消息。

默认情况下,您的策略具有非持久性连接,并且没有为此连接传递任何属性。如果您想要具有持久连接,则必须在 IAM 策略中指定持久连接。

有关 ConnectAttributes 示例,请参阅连接策略示例

MQTT 5 支持的特征

Amazon IoT Core 对 MQTT 5 的支持基于 MQTT v5.0 规范,但有一些差异,如 Amazon IoT 与 MQTT 规范不同 中所述。

共享订阅

Amazon IoT Core 对于 MQTT 3 和 MQTT 5 支持共享订阅。共享订阅允许多个客户端共享对某个主题的订阅,并且只有一个客户端会收到使用随机分布发布到该主题的消息。共享订阅可以有效地在多个订阅用户之间对 MQTT 消息实现负载均衡。例如,假设您有 1000 台设备发布到同一个主题,有 10 个后端应用程序正在处理这些消息。在这种情况下,后端应用程序可以订阅同一个主题,并且每个应用程序都会随机接收设备向共享主题发布的消息。这实际上是“共享”这些消息的负载。共享订阅还可以提高弹性。当任何后端应用程序断开连接时,代理会将负载分配给组中剩余的订阅用户。

要使用共享订阅,客户需要按如下方式订阅共享订阅的主题筛选条件

$share/{ShareName}/{TopicFilter}
  • $share 是一个文本字符串,用于表示共享订阅的主题筛选条件,该筛选条件必须以 $share 开头。

  • {ShareName} 是一个字符串,用于指定一组订阅用户使用的共享名称。共享订阅的主题筛选条件必须包含 ShareName 且后跟 / 字符。{ShareName} 不得包含以下字符:/+#{ShareName} 的最大大小为 128 字节。

  • {TopicFilter} 遵循与非共享订阅相同的主题筛选条件语法。{TopicFilter} 的最大大小为 256 字节。

  • $share/{ShareName}/{TopicFilter} 所需的两个斜杠(/)不包括在主题和主题筛选条件中的最大斜杠数限制中。

具有相同 {ShareName}/{TopicFilter} 的订阅属于同一个共享订阅组。您可以创建多个共享订阅组,但不要超过每个组的共享订阅限制。有关更多信息,请参阅 Amazon 一般参考中的 Amazon IoT Core 端点和配额

下面的各个表比较了非共享订阅和共享订阅:

订阅 描述 主题筛选条件示例
非共享订阅 每个客户端创建单独的订阅以接收已发布的消息。当消息发布到某个主题时,该主题的所有订阅用户都会收到该消息的副本。
sports/tennis sports/#
共享订阅 多个客户端可以共享对一个主题的订阅,并且只有一个客户端会收到以随机分布方式发布到该主题的消息。
$share/consumer/sports/tennis $share/consumer/sports/#
非共享订阅流程 共享订阅流程

                                        常规(非共享)订阅

                                        共享订阅

使用共享订阅的重要注意事项

  • 当针对 QoS0 订阅用户的发布尝试失败时,不会尝试进行重试,并且消息将被丢弃。

  • 当针对具有干净会话的 QoS1 订阅用户的发布尝试失败时,该消息将发送给该组中的另一个订阅用户以尝试进行多次重试。在尝试所有重试后仍未能传送的消息将被丢弃。

  • 当针对具有持久性会话的 QoS1 订阅用户的发布尝试因订阅用户处于离线状态而失败时,消息将不会排队,而是会尝试发送给组中的其他订阅用户。在尝试所有重试后仍未能传送的消息将被丢弃。

  • 共享订阅不接收保留的消息

  • 当共享订阅包含通配符(# 或 +)时,一个主题可能有多个匹配的共享订阅。如果发生这种情况,消息代理会复制发布消息,并将其发送给每个匹配的共享订阅中的随机客户端。下图可以解释共享订阅的通配符行为。

    在此示例中,有三个与发布 MQTT 主题 sports/tennis 匹配的共享订阅。消息代理复制已发布的消息,并将消息发送给每个匹配组中的随机客户端。

    客户端 1 和客户端 2 共享订阅:$share/consumer1/sports/tennis

    客户端 3 和客户端 4 共享订阅:$share/consumer1/sports/#

    客户端 5 和客户端 6 共享订阅:$share/consumer2/sports/tennis

有关共享订阅限制的更多信息,请参阅《Amazon 一般参考》中的 Amazon IoT Core 端点和限额。要在 Amazon IoT 控制台中使用 Amazon IoT MQTT 客户端测试共享订阅,请参阅在 MQTT 客户端中测试共享订阅。有关共享订阅的更多信息,请参阅 MQTTv5.0 规范中的共享订阅

干净启动和会话过期

您可以使用“干净启动”和“会话过期”来更灵活地处理持久性会话。干净启动标志指示是否应在不使用现有会话的情况下启动会话。会话过期间隔指示断开连接后会话保持多长时间。可以在断开连接后修改会话过期间隔。有关更多信息,请参阅MQTT 持久性会话

所有 ACK 上的原因代码

您可以使用原因代码更轻松地调试或处理错误消息。消息代理根据与代理的交互类型(订阅、发布、确认)返回原因代码。有关更多信息,请参阅 MQTT 原因代码。有关 MQTT 原因代码的完整列表,请参阅 MQTT v5 规范

主题别名

您可以将主题名称替换为主题别名,主题别名是一个双字节整数。使用主题别名可以优化主题名称的传输,从而有可能降低计量数据服务的数据成本。Amazon IoT Core 默认限制为 8 个主题别名。有关更多信息,请参阅 Amazon 一般参考中的 Amazon IoT Core 端点和配额

消息过期

您可以向已发布的消息添加消息过期值。这些值表示消息过期间隔(以秒为单位)。如果未在该间隔内将消息发送给订阅者,该消息将过期并被删除。如果不设置消息过期值,消息会过期。

在出站时,订阅者将收到一条消息,其中包含到期间隔内的剩余时间。例如,如果入站发布消息的消息过期间隔为 30 秒,并且在 20 秒后路由到订阅者,则消息过期字段将更新为 10。订阅者收到的消息的更新后的 MEI 可能为 0。这是因为只要剩余时间为 999 毫秒或更短,它就会更新为 0。

在 Amazon IoT Core 中,最短消息过期间隔为 1。如果从客户端将间隔设置为 0,则间隔将调整为 1。最长消息过期间隔为 604800(7 天)。高于此值的任何值都将调整为最大值。

在跨版本通信中,消息过期的行为由入站发布消息的 MQTT 版本决定。例如,通过 MQTT5 连接的会话发送的消息过期消息可能会对订阅 MQTT3 会话的设备过期。下表列出了消息过期如何支持以下类型的发布消息:

发布消息类型 消息过期间隔
定期发布 如果服务器未能在指定时间内传送消息,则过期的消息将被删除,订阅者将无法收到该消息。这包括设备未发布确诊其 QoS 1 消息等情况。
保留 如果保留消息过期,而新客户端订阅了该主题,则该客户端在订阅后将不会收到该消息。
最后遗嘱 最后遗嘱消息间隔是在客户端断开连接,并且服务器尝试向其订阅者传送最后遗嘱消息之后开始的。
已排队消息 如果具有消息过期间隔的出站 QoS1 在客户端离线时过期,则持久性会话恢复后,客户端将不会收到过期的消息。

其它 MQTT 5 特征

服务器断开连接

断开连接时,服务器可以主动向客户端发送 DISCONNECT,以通知连接关闭,同时发送断开连接的原因代码。

请求/响应

发布者可以请求接收方在收到时向发布者指定的主题发送响应。

最大数据包大小

客户端和服务器可以独立指定它们支持的最大数据包大小。

负载格式和内容类型

发布消息时,您可以指定负载格式(二进制、文本)和内容类型。这些消息将被转发给消息的接收者。

MQTT 5 属性

MQTT 5 属性是 MQTT 标准的重要补充,用于支持新的 MQTT 5 特征,例如会话过期和请求/响应模式。在 Amazon IoT Core 中,您可以创建规则来转发出站消息中的属性,也可以使用 HTTP 发布来发布带有一些新属性的 MQTT 消息。

下表列出了 Amazon IoT Core 支持的所有 MQTT 5 属性。

属性 描述 输入类型 数据包
负载格式指示符 一个布尔值,指示负载是否格式化为 UTF-8。 字节 PUBLISH、CONNECT
内容类型 一个描述负载内容的 UTF-8 字符串。 UTF-8 字符串 PUBLISH、CONNECT
回复主题 一个 UTF-8 字符串,描述接收方作为请求-响应流程的一部分应发布到的主题。主题不得包含通配符。 UTF-8 字符串 PUBLISH、CONNECT
关联数据 请求消息的发送者用来指示回复消息回复哪个请求的二进制数据。 二进制 PUBLISH、CONNECT
用户属性 一对 UTF-8 字符串。此属性可以在一个数据包中出现多次。接收者将按照键-值对的发送顺序接收键-值对。 UTF-8 字符串对 CONNECT、PUBLISH、Will Properties、SUBSCRIBE、DISCONNECT、UNSUBSCRIBE
消息过期间隔 一个 4 字节整数,表示消息过期间隔(以秒为单位)。如果此数值不存在,消息永远不会过期。 4 字节整数 PUBLISH、CONNECT
会话过期间隔

一个 4 字节整数,表示会话过期间隔(以秒为单位)。Amazon IoT Core 最多支持 7 天,默认最长一小时。如果您设置的值超过账户的最大值,Amazon IoT Core 将在 CONNACK 中返回调整后的值。

4 字节整数 CONNECT、CONNACK、DISCONNECT
分配的客户端标识符 设备未指定客户端 ID 时,Amazon IoT Core 生成的随机客户端 ID。随机客户端 ID 必须是代理当前管理的任何其他会话都未使用的新客户端标识符。 UTF-8 字符串 CONNACK
服务器保持活动 一个 2 字节整数,表示服务器分配的保持活动时间。如果客户端处于非活动状态的时间超过保持活状态的动时间,服务器将断开客户端的连接。 2 字节整数 CONNACK
请求问题信息 一个布尔值,表示在失败时是发送原因字符串还是用户属性。 字节 连接
接收最大值 一个 2 字节整数,表示在未收到 PUBACK 的情况下可以发送的 PUBLISH QOS > 0 数据包的最大数量。 2 字节整数 CONNECT、CONNACK
主题别名最大值 此值表示将被接受作为主题别名的最大值。默认值为 0。 2 字节整数 CONNECT、CONNACK
最大 QoS 数 Amazon IoT Core 支持的 QoS 的最大值。默认值为 1。Amazon IoT Core 不支持 QoS2。 字节 CONNACK
保留可用

一个布尔值,表示 Amazon IoT Core 消息代理是否支持保留的消息。默认值为 1。

字节 CONNACK
最大数据包大小 Amazon IoT Core 接收和发送的最大数据包大小。不能超过 128 KB。 4 字节整数 CONNECT、CONNACK
通配符订阅可用

一个布尔值,指示 Amazon IoT Core 消息代理是否支持通配符订阅可用。默认值为 1。

字节 CONNACK
订阅标识符可用

一个布尔值,指示 Amazon IoT Core 消息代理是否支持订阅标识符可用。默认值为 0。

字节 CONNACK

MQTT 原因代码

MQTT 5 通过原因代码响应改进了错误报告。Amazon IoT Core 可能会返回原因代码,包括但不限于以下按数据包分组的原因代码。有关 MQTT 支持的原因代码的完整列表,请参阅 MQTT 5 规范

CONNACK 原因代码
Value 十六进制 原因代码名称 描述
0 0x00 成功 连接被接受。
128 0x80 未指定的错误 服务器不希望透露失败的原因,或者其他原因代码都不适用。
133 0x85 客户端标识符无效 客户端标识符是有效的字符串,但服务器不允许使用。
134 0x86 用户名或密码错误 服务器不接受客户端指定的用户名或密码。
135 0x87 未授权 客户端无权连接。
144 0x90 主题名称无效 遗嘱主题名称格式正确,但未被服务器接受。
151 0x97 超出配额 已超出实施或管理施加的限制。
155 0x9B 不支持 QoS 服务器不支持遗嘱 QoS 中设置的 QoS。
PUBACK 原因代码
Value 十六进制 原因代码名称 描述
0 0x00 成功 该消息已被接受。继续发布 QoS 1 消息。
128 0x80 未指定的错误 接收者不接受发布,但要么不想透露原因,要么与其他值不匹配。
135 0x87 未授权 PUBLISH 未经授权。
144 0x90 主题名称无效 主题名称格式正确,但不被客户端或服务器接受。
145 0x91 正在使用数据包标识符 数据包标识符已在使用中。这可能表示客户端和服务器之间的会话状态不匹配。
151 0x97 超出配额 已超出实施或管理施加的限制。
断开连接原因代码
Value 十六进制 原因代码名称 描述
129 0x81 数据包格式不正确 收到的数据包不符合此规范。
130 0x82 协议错误 收到意外或无序的数据包。
135 0x87 未授权 请求未经授权。
139 0x8B 服务器正在关闭 服务器正在关闭。
141 0x8D 保持活动状态超时 连接已关闭,因为在 1.5 倍的保持活动状态时间内没有收到任何数据包。
142 0x8E 会话已接管 使用相同 ClientID 的另一个连接已连接,导致此连接关闭。
143 0x8F 主题筛选条件无效 主题筛选条件格式正确,但未被服务器接受。
144 0x90 主题名称无效 主题名称格式正确,但未被该客户端或服务器接受。
147 0x93 超出最大接收数 客户端或服务器收到的发布数超过了未发送 PUBACK 或 PUBCOMP 的最大接收数。
148 0x94 主题别名无效 客户端或服务器收到了一个 PUBLISH 数据包,其中包含的主题别名大于其在 CONNECT 或 CONNACK 数据包中发送的最大主题别名。
151 0x97 超出配额 已超出实施或管理施加的限制。
152 0x98 管理操作 由于管理操作,连接已关闭。
155 0x9B 不支持 QoS 客户端指定的 QoS 大于 CONNACK 的“最大 QoS”中指定的 QoS。
161 0xA1 不支持订阅标识符 服务器不支持订阅标识符;不接受订阅。
PUBACK 原因代码
Value 十六进制 原因代码名称 描述
0 0x00 授予的 QoS 0 接受订阅,发送的最大 QoS 将为 QoS 0。这可能比请求的 QoS 低。
1 0x01 授予的 QoS 1 接受订阅,发送的最大 QoS 将为 QoS 1。这可能比请求的 QoS 低。
128 0x80 未指定的错误 未接受订阅,要么服务器不希望透露原因,要么其他原因代码都不适用。
135 0x87 未授权 客户端无权进行此订阅。
143 0x8F 主题筛选条件无效 主题筛选条件格式正确,但不允许此客户端使用。
145 0x91 正在使用数据包标识符 指定的数据包标识符已在使用中。
151 0x97 超出配额 已超出实施或管理施加的限制。
UNSUBACK 原因代码
Value 十六进制 原因代码名称 描述
0 0x00 成功 订阅将被删除。
128 0x80 未指定的错误 无法完成取消订阅,要么服务器不希望透露原因,要么其他原因代码都不适用。
143 0x8F 主题筛选条件无效 主题筛选条件格式正确,但不允许此客户端使用。
145 0x91 正在使用数据包标识符 指定的数据包标识符已在使用中。

Amazon IoT 与 MQTT 规范不同

尽管消息代理的实施基于 MQTT v3.1.1 规范MQTT v5.0 规范,但与这些规范有如下区别:

  • Amazon IoT 不支持 MQTT 3 的以下数据包:PUBREC、PUBREL 和 PUBCOMP。

  • Amazon IoT 不支持 MQTT 5 的以下数据包:PUBREC、PUBREL 和 PUBCOMP。

  • Amazon IoT 不支持 MQTT 5 服务器重定向。

  • Amazon IoT 仅支持 MQTT 服务质量 (QoS) 级别 0 和 1。Amazon IoT 不支持使用 QoS 级别 2 进行发布或订阅。在请求 QoS 级别 2 时,消息代理不会发送 PUBACK 或 SUBACK。

  • 在 Amazon IoT 中,订阅具有 QoS 级别 0 的主题意味着将消息传送零次或多次。消息可能会多次发送。多次发送的消息在发送时可能会使用不同的数据包 ID。在这些情况下,不会设置 DUP 标志。

  • 在响应连接请求时,消息代理将发送 CONNACK 消息。此消息包含一个标志,用于指明该连接是否会恢复上一个会话。

  • 在发送其它控制数据包或断开连接请求之前,客户端必须等待从 Amazon IoT 消息代理发送到设备的 CONNACK 消息。

  • 当客户端订阅主题时,在消息代理开始发送 SUBACK 和客户端开始收到新的匹配消息之间存在时间延迟。

  • 当客户端在订阅主题的主题过滤条件中使用通配符 # 时,主题层次结构中处于及其级别以下的所有字符串均会匹配。但是,父主题不匹配。例如,订阅主题 sensor/# 接收发布到主题sensor/sensor/temperaturesensor/temperature/room1 的消息,但不是发布到 sensor 的消息。有关通配符的更多信息,请参阅 主题筛选条件

  • 消息代理使用客户端 ID 标识每个客户。客户端 ID 作为 MQTT 负载的一部分从客户端传递到消息代理。客户端 ID 相同的两个客户端无法同时连接到消息代理。当某个客户端使用另一客户端正在使用的客户端 ID 连接到消息代理时,会接受新的客户端连接,而之前连接的客户端会断开连接。

  • 在极少数情况下,消息代理可能会使用不同的数据包 ID 再次发送相同的逻辑 PUBLISH 消息。

  • 订阅包含通配符的主题筛选条件无法接收保留消息。要接收保留消息,订阅请求必须包含与保留消息主题完全匹配的主题筛选条件。

  • 消息代理并不保证收到消息和 ACK 的顺序。

  • Amazon IoT 可能具有与这些规格不同的限制。有关更多信息,请参阅《Amazon IoT 参考指南》中的Amazon IoT Core消息代理和协议限制与限额