

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 直接傳訊
<a name="direct-messaging"></a>

AWS IoT Core 現在支援直接傳訊。您可以依 MQTT 用戶端 ID 傳送訊息至單一連線裝置，而不需要裝置訂閱主題。

先前，將訊息傳送至需要發佈至裝置訂閱之主題的特定裝置，而沒有確認交付的內建方式。寄件者呼叫 SendDirectMessage HTTP API，指定接收者的用戶端 ID 和目標主題。當 時`confirmation=true`， 會在 QoS 1 AWS IoT Core 傳送並等待接收者的 PUBACK，然後再傳回成功的回應。這可為您提供end-to-end交付確認。API 回應和 Amazon CloudWatch Logs 提供交付狀態和失敗原因的完整可見性。

 AWS 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`許可 - 無需主題訂閱即可 AWS 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}} 是 [AWS IoT 裝置資料端點](iot-connect-devices.md#iot-connect-device-endpoints)。請參閱 [AWS IoT 裝置資料和服務端點](iot-connect-devices.md#iot-connect-device-endpoints) 尋找您的端點。
+ {{client\_id}} 是要傳送訊息之 MQTT 用戶端的唯一識別符。客戶 IDs 不得超過 128 個字元，且開頭不得為貨幣符號 ($)。當 MQTT 用戶端 IDs 包含 HTTP 請求中無效的字元時，例如空格、正斜線 (/) 和 UTF-8 字元，則必須使用 URL 編碼 （百分比編碼）。如需詳細資訊，請參閱[AWS IoT Core 訊息中介裝置和通訊協定限制和配額](https://docs.aws.amazon.com/general/latest/gr/iot-core.html#message-broker-limits)。
+ {{topic\_name}} 是接收者收到 URL 編碼訊息的主題。開頭不得為 $。不得為 AWS IoT Core 預留主題。如需主題長度和深度限制，請參閱 AWS IoT Core 服務配額頁面。如需詳細資訊，請參閱[AWS IoT Core 訊息中介裝置和通訊協定限制和配額](https://docs.aws.amazon.com/general/latest/gr/iot-core.html#message-broker-limits)。
+ {{confirmation}} 是布林值。設為 時`true`，API 會在 QoS 1 傳送訊息，並等待 MQTT 用戶端傳送交付確認 (PUBACK)，再傳回成功回應。如果未在指定的逾時期間內收到交付確認，API 會傳回 HTTP 504。
+ {{逾時}}是整數，代表訊息交付後等待來自接收用戶端的交付確認 (PUBACK) 的最長時間，以秒為單位。只有在 `confirmation` 設定為 時，才會使用此參數`true`。如果 `confirmation`是 `false`，則會忽略此參數。由於內部處理，總 API 回應時間可能高於此值。將您的 HTTP 用戶端逾時設定為大於此參數的值。

### API 回應狀態碼
<a name="direct-messaging-response-codes"></a>

下表列出 SendDirectMessage API 傳回的 HTTP 狀態碼，以及每個 API 的建議動作。啟用 AWS IoT Core CloudWatch 日誌以查看詳細的 SendDirectMessage 事件日誌，包括程式設計錯誤處理的原因欄位。


**SendDirectMessage API 回應狀態碼**  

| HTTP 代碼 | 建議的動作 | 
| --- | --- | 
| 200 OK | 如果使用 請求交付確認confirmation=true，這表示接收者已確認收到訊息。否則，這表示訊息已成功分派。 | 
| 400 錯誤的請求 | 這表示其中一個參數無效。檢閱 HTTP 回應訊息或 CloudWatch 日誌，以識別特定失敗和修正。確保主題名稱和 Client-id 有效且 URL 編碼正確。 | 
| 403 禁止 | 這表示寄件者的政策不會在目標用戶端和主題iot:SendDirectMessage上授予 ，或者接收者的政策不會在主題iot:Receive上授予 。檢閱 HTTP 回應訊息或 CloudWatch 日誌以識別特定失敗，並更新對應的政策。請參閱 [直接傳訊政策範例](direct-messaging-policy-examples.md)。 | 
| 404 找不到 | 這表示目標用戶端 ID 未連線 AWS IoT Core。基於特定原因檢閱 HTTP 回應訊息或 CloudWatch 日誌，確認接收器已連線，然後再試一次。如果回應訊息指出「目標用戶端 ID 未連線，但其具有作用中的持久性工作階段」，則目標用戶端具有未過期的持久性工作階段，但目前處於離線狀態。 | 
| 413 承載過大 | 承載超過允許的大小上限。減少承載大小並重試。請參閱[AWS IoT Core 服務配額](https://docs.aws.amazon.com/general/latest/gr/iot-core.html)。 | 
| 429 太多請求 | 這表示帳戶已超過 SendDirectMessage requests-per-second數限制，或接收者連線已超過傳出發佈限制。檢閱 HTTP 回應訊息或 CloudWatch 日誌以了解特定原因、降低請求率並實作指數退避。請參閱[AWS IoT Core 服務配額](https://docs.aws.amazon.com/general/latest/gr/iot-core.html)。 | 
| 500 內部伺服器錯誤 | 這表示未預期的伺服器端錯誤。以指數退避重試請求。如果問題仍然存在，請聯絡 AWS Support with the traceId from the response。 | 
| 504 閘道逾時 | 這表示接收者未在指定的逾時期間內傳送 PUBACK。增加逾時值、確認接收者的 MQTT 用戶端為 QoS 1 訊息傳送 PUBACK，或檢查接收者是否處理訊息緩慢。 | 

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

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

如果您使用的是第 2 AWS Command Line Interface 版，則需要 `--cli-binary-format`選項。若要讓此成為預設的設定，請執行 `aws configure set cli-binary-format raw-in-base64-out`。若要取得更多資訊，請參閱*《AWS Command Line Interface 使用者指南第 2 版》*中 [AWS CLI 支援的全域命令列選項](https://docs.aws.amazon.com/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 決定的 QoS ** — 交付訊息的 QoS 層級是由寄件者的 API 請求中的 `confirmation` 參數設定，而不是由接收者的訂閱設定。當 時`confirmation=true`，訊息到達 QoS 1，接收者的用戶端必須傳送 PUBACK 以確認傳遞。當 時`confirmation=false`，訊息會到達 QoS 0，而不需要確認。確保您的用戶端的 MQTT 實作正確處理 QoS 0 和 QoS 1 傳入訊息。