

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

# 直接消息
<a name="direct-messaging"></a>

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

以前，向特定设备发送消息需要发布到该设备订阅的主题，但没有内置的方法来确认传送。发送方调用 SendDirectMessage HTTP API，指定接收方的客户端 ID 和目标主题。何时`confirmation=true`， Amazon IoT Core 以 QoS 1 进行交付，等待接收方的 PUBACK 后再返回成功响应。这为您提供了端到端的交付确认。API 响应和 Ama CloudWatch zon Logs 可全面了解交付状态和失败原因。

私信不由 Amazon IoT 规则执行规则处理，不排队等候离线设备，也不支持保留的消息。

**Topics**
+ [先决条件](#direct-messaging-prerequisites)
+ [SendDirectMessage API](#direct-messaging-api)
+ [接收方客户端行为](#direct-messaging-receiver)

## 先决条件
<a name="direct-messaging-prerequisites"></a>

发送方和接收方都需要采取特定的策略操作才能使用直接消息。发件人必须拥有`iot:SendDirectMessage`权限。目标客户端 ID 被指定为资源，`iot:Topic`条件键（可选）限制发件人可以直接发送消息的主题。接收者必须拥有目标主题的`iot:Receive`权限。接收者不需要`iot:Subscribe`许可 — Amazon IoT Core 无需订阅主题即可直接发送消息。有关更多详细信息和策略示例，请参阅[私信策略示例](direct-messaging-policy-examples.md)。

有关 HTTP 请求使用的身份验证和端口映射，请参阅 [协议、端口映射和身份验证](protocols.md#protocol-mapping)。

## SendDirectMessage API
<a name="direct-messaging-api"></a>

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

```
https://{{IoT_data_endpoint}}/connections/{{client_id}}/messages?topic={{topic_name}}&confirmation=true&timeout=10
```
+ {{IoT\_data\_endpoint}}是[Amazon IoT 设备数据端点](iot-connect-devices.md#iot-connect-device-endpoints)。[Amazon IoT 设备数据和服务端点](iot-connect-devices.md#iot-connect-device-endpoints)要查找您的终端节点，请参阅。
+ {{client\_id}}是要向其发送消息的 MQTT 客户端的唯一标识符。客户端 ID 不得超过 128 个字符，并且不能以美元符号 ($) 开头。当 MQTT 客户端 ID 包含在 HTTP 请求中无效的字符（例如空格、正斜杠 (/) 和字符）时，必须进行网址编码（百分比编码）。 UTF-8 有关更多信息，请参阅[Amazon IoT Core 消息代理和协议限制和配额](https://docs.amazonaws.cn//general/latest/gr/iot-core.html#message-broker-limits)。
+ {{topic\_name}}是接收者收到消息的主题 URL-encoded。不能以 $ 开头。不得为 Amazon IoT Core 保留话题。有关主题长度和深度限制，请参阅 Amazon IoT Core 服务配额页面。有关更多信息，请参阅[Amazon IoT Core 消息代理和协议限制和配额](https://docs.amazonaws.cn//general/latest/gr/iot-core.html#message-broker-limits)。
+ {{confirmation}}是一个布尔值。设置为时`true`，API 将按照 QoS 1 发送消息，并等待 MQTT 客户端发送传送确认 (PUBACK)，然后再返回成功响应。如果在指定的超时时间内未收到传送确认，API 将返回 HTTP 504。
+ {{timeout}}是一个整数，表示消息传送后等待接收客户端的传送确认 (PUBACK) 的最长时间（以秒为单位）。此参数仅在设置`confirmation`为时使用`true`。如果`confirmation`是`false`，则忽略此参数。由于内部处理的原因，API 的总响应时间可能高于此值。将 HTTP 客户端超时设置为大于此参数的值。

### API 响应状态码
<a name="direct-messaging-response-codes"></a>

下表列出了 SendDirectMessage API 返回的 HTTP 状态码以及每个状态码的建议操作。启用 Amazon 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 日志以确定具体故障，并更新相应的策略。请参阅[私信策略示例](direct-messaging-policy-examples.md)。 | 
| 404 未找到 | 这意味着目标客户端 ID 未连接到 Amazon IoT Core。查看 HTTP 响应消息或 CloudWatch 日志以了解具体原因，确认接收器已连接，然后重试。如果响应消息显示 “目标客户端 ID 未连接，但其持续会话处于活动状态”，则目标客户端的持续会话未过期，但当前处于脱机状态。 | 
| 413 有效载荷太大 | 有效载荷超过允许的最大大小。减小有效载荷大小并重试。请参阅 [Amazon IoT Core 服务限额](https://docs.amazonaws.cn//general/latest/gr/iot-core.html)。 | 
| 429 请求过多 | 这意味着该账户已超过 SendDirectMessage 每秒请求数限制，或者接收方连接已超过出站发布限制。查看 HTTP 响应消息或 CloudWatch 日志以了解具体原因，降低请求速率并实现指数级退避。请参阅 [Amazon IoT Core 服务限额](https://docs.amazonaws.cn//general/latest/gr/iot-core.html)。 | 
| 500 内部服务器错误 | 这表示服务器端出现意外错误。使用指数退避重试请求。如果问题仍然存在，请使用响应中的 traceID 与 Support 联系 Amazon 。 | 
| 504 网关超时 | 这意味着接收方没有在指定的超时时间内发送 PUBACK。增加超时值，验证接收方的 MQTT 客户端发送 PUBACK for QoS 1 消息，或者检查接收方处理消息的速度是否缓慢。 | 

### 示例
<a name="direct-messaging-examples"></a>

------
#### [ Amazon 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}}
```

如果您使用的是 Amazon Command Line Interface 版本 2，则该`--cli-binary-format`选项为必填项。要将其设为默认设置，请运行 `aws configure set cli-binary-format raw-in-base64-out`。有关更多信息，请参阅*版本 2 的Amazon Command Line Interface 用户指南*中的 [Amazon CLI 支持的全局命令行选项](https://docs.amazonaws.cn/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。

------
#### [ 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"
```

------

## 接收方客户端行为
<a name="direct-messaging-receiver"></a>

直接消息无需订阅主题即可向 MQTT 客户端（接收者）发送消息。要充分受益于直接消息，接收者必须支持以下行为：
+ **接收有关未明确订阅的主题的消息**-接收者的直接消息可以将消息传送到接收者未明确订阅的主题。但是，某些 MQTT 客户端实现会筛选或丢弃已取消订阅的主题上的消息。如果您的客户丢弃了这些消息，则直接消息仅适用于接收者也已订阅的主题。要接收有关任何主题的直接消息，请验证无论订阅状态如何，您的客户端的消息处理程序都处理消息。
+ **处理由 API 决定的 Qo** S — 已发送消息的 QoS 级别由发送者 API 请求中的`confirmation`参数设置，而不是由接收方的订阅设置。当消息到达 QoS 1 时`confirmation=true`，接收方的客户端必须发送 PUBACK 以确认传送。何时`confirmation=false`，消息到达 QoS 0 时无需确认。确保您的客户端的 MQTT 实现能够正确处理 QoS 0 和 QoS 1 传入消息。