View a markdown version of this page

直接消息 - AWS IoT Core

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

直接消息

AWS IoT Core 现在支持直接消息。您可以通过单个连接的设备的 MQTT 客户端 ID 向其发送消息,无需设备订阅主题。

以前,向特定设备发送消息需要发布到设备订阅的主题,而没有内置的方法可以确认传送。发送者调用 SendDirectMessage HTTP API,指定接收者的客户端 ID 和目标主题。当时confirmation=true, AWS IoT Core 以 QoS 1 进行交付,等待接收方的 PUBACK,然后返回成功的响应。这为您提供了端到端的交付确认。API 响应和亚马逊 CloudWatch 日志让您可以全面了解交付状态和失败原因。

私信不由 AWS IoT 规则处理以执行规则,不排队等待离线设备,也不支持保留的消息。

先决条件

发送方和接收方都需要特定的策略操作才能使用直接消息。发件人必须有iot:SendDirectMessage权限。目标客户端 ID 被指定为资源,iot:Topic条件密钥(可选)限制发件人可以发送直接消息的主题。接收者必须拥有目标主题的iot:Receive权限。接收者不需要iot:Subscribe许可—— AWS IoT Core 无需订阅主题即可直接发送消息。有关更多详细信息和示例策略,请参阅直接消息策略示例。

有关 HTTP 请求使用的身份验证和端口映射,请参阅 协议、端口映射和身份验证。

SendDirectMessage API

发件人可以通过向特定客户的 URL 发出 HTTP POST 请求来发送私信:

https://IoT_data_endpoint/connections/client_id/messages?topic=topic_name&confirmation=true&timeout=10
  • IoT_data_endpoint是AWS IoT 设备数据端点。请参阅AWS IoT 设备数据和服务端点查找您的终端节点。

  • client_id是发送消息的 MQTT 客户端的唯一标识符。客户端 ID 不得超过 128 个字符,并且不能以美元符号 ($) 开头。如果 MQTT 客户端 ID 包含在 HTTP 请求中无效的字符,例如空格、正斜杠 (/) 和字符,则必须采用 URL 编码(百分比编码)。 UTF-8 有关更多信息,请参阅AWS IoT Core 消息代理和协议限制和配额。

  • topic_name是接收者接收消息的主题, URL-encoded。不得以 $ 开头。不得是 AWS IoT Core 保留主题。有关主题长度和深度限制,请参阅 AWS IoT Core 服务配额页面。有关更多信息,请参阅AWS IoT Core 消息代理和协议限制和配额。

  • confirmation是一个布尔值。如果设置为true,API 将在 QoS 1 下传送消息,并等待 MQTT 客户端发送传送确认 (PUBACK),然后返回成功的响应。如果在指定的超时时间内未收到交付确认,则 API 返回 HTTP 504。

  • timeout是一个整数,表示消息传送后等待接收客户端的传送确认 (PUBACK) 的最长时间(以秒为单位)。此参数仅在设置confirmation为时使用true。如果confirmation是false,则忽略此参数。由于内部处理,API 总响应时间可能高于该值。将 HTTP 客户端超时设置为大于此参数的值。

API 响应状态码

下表列出了 SendDirectMessage API 返回的 HTTP 状态码以及每个状态码的推荐操作。启用 AWS IoT Core CloudWatch 日志以查看详细 SendDirectMessage 的事件日志,包括编程错误处理的原因字段。

SendDirectMessage API 响应状态码
HTTP 代码 推荐操作
200 OK (200 确定) 如果请求发送确认confirmation=true,则表示接收方已确认收到消息。否则,这表示消息已成功发送。
400 错误请求 这意味着其中一个参数无效。查看 HTTP 响应消息或 CloudWatch 日志,找出具体的故障并进行修复。确保主题名称和有效 Client-id 且 URL-encoded正确。
403 禁止访问 这意味着发送者的策略不iot:SendDirectMessage对目标客户端和主题进行授权,或者接收者的政策不iot:Receive对该主题进行授权。查看 HTTP 响应消息或 CloudWatch 日志以确定特定的故障,并更新相应的策略。请参阅直接消息策略示例。
404 未找到 这意味着目标客户端 ID 未连接到 AWS IoT Core。查看 HTTP 响应消息或 CloudWatch 日志以了解具体原因,验证接收器是否已连接,然后重试。如果响应消息显示 “目标客户端 ID 未连接,但它有一个活跃的持续会话”,则目标客户端的永久会话未过期,但当前处于脱机状态。
413 有效载荷太大 有效载荷超过允许的最大大小。减小负载大小并重试。请参阅 AWS IoT Core 服务限额。
429 请求过多 这意味着该账户已超过 SendDirectMessage 每秒请求数限制或接收方连接已超过出站发布限制。查看 HTTP 响应消息或 CloudWatch 日志以了解具体原因,降低请求速率并实施指数退避。请参阅 AWS IoT Core 服务限额。
500 内部服务器错误 这表示服务器端出现意外错误。使用指数退避重试请求。如果问题仍然存在,请使用回复中的 TraceID 与 AWS 支持部门联系。
504 网关超时 这意味着接收方没有在指定的超时时间内发送 PUBACK。增加超时值,验证接收方的 MQTT 客户端为 QoS 1 消息发送 PUBACK,或者检查接收器处理消息的速度是否缓慢。

示例

AWS CLI
aws iot-data send-direct-message \ --client-id myDevice \ --topic commands/reboot \ --confirmation \ --timeout 10 \ --payload '{"action": "reboot"}' \ --cli-binary-format raw-in-base64-out \ --region us-west-2 \ --endpoint-url https://IoT_data_endpoint

如果您使用的是 AWS Command Line Interface 版本 2,则该--cli-binary-format选项为必填选项。要将其设为默认设置,请运行 aws configure set cli-binary-format raw-in-base64-out。有关更多信息,请参阅版本 2 的AWS Command Line Interface 用户指南中的 AWS CLI 支持的全局命令行选项。

curl (X.509 client certificate, port 8443)
curl --tlsv1.2 \ --cacert Amazon-root-CA-1.pem \ --cert device.pem.crt \ --key private.pem.key \ --request POST \ --data '{"action": "reboot"}' \ "https://IoT_data_endpoint:8443/connections/myDevice/messages?topic=commands%2Freboot&confirmation=true&timeout=10"

接收者客户的行为

直接消息无需订阅主题即可向 MQTT 客户端(接收者)传送消息。为了充分受益于直接消息,接收者必须支持以下行为:

  • 接收有关未明确订阅的主题的消息 -接收者的直接消息可以向接收者未明确订阅的主题传送消息。但是,某些 MQTT 客户端实现会筛选或丢弃有关取消订阅主题的消息。如果您的客户丢弃了这些消息,则直接消息将仅适用于接收者也订阅的话题。要接收有关任何主题的直接消息,请验证无论订阅状态如何,您的客户端的消息处理程序都会处理消息。

  • 处理由 API 确定的 QoS — 传送消息的 QoS 级别由发送者的 API 请求中的confirmation参数设置,而不是由接收者的订阅设置。当消息到达 QoS 1 时confirmation=true,接收方的客户端必须发送 PUBACK 以确认传送。当confirmation=false消息到达 QoS 0 时,无需确认。确保您的客户端的 MQTT 实现可以正确处理 QoS 0 和 QoS 1 的传入消息。