

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

# 在應用程式和服務中使用影子
<a name="device-shadow-comms-app"></a>

本節說明應用程式或服務如何與 AWS IoT Device Shadow 服務互動。此範例假設應用程式或服務只透過影子與影子與該裝置互動。此範例不包含任何管理動作，例如建立或刪除影子。

此範例使用 AWS IoT Device Shadow 服務的 REST API 與陰影互動。與用於 [在裝置中使用影子](device-shadow-comms-device.md) 中的範例 (使用發佈/訂閱通訊模型) 不同，此範例使用 REST API 的請求/回應通訊模型。這表示應用程式或服務必須先提出請求，才能從中接收回應 AWS IoT。不過，此模型的缺點是它不支援通知。如果您的應用程式或服務需要及時通知裝置狀態變更，請考慮透過 WSS 通訊協定支援發佈/訂閱通訊模型的 MQTT 或 MQTT，如中所述 [在裝置中使用影子](device-shadow-comms-device.md)。

**重要**  
請確定您的應用程式或服務對影子的使用與裝置中的對應實作一致，並支援這些功能。例如，請考慮如何建立、更新和刪除影子，以及如何在裝置和存取影子的應用程式或服務中處理更新。您的設計應該清楚指定裝置狀態的更新和報告方式，以及您的應用程式和服務如何與裝置及其影子互動。

REST API 的已命名影子 URL 是：

```
https://endpoint/things/thingName/shadow?name=shadowName
```

和一個未命名的影子：

```
https://endpoint/things/thingName/shadow
```

其中：

端點  
CLI 命令傳回的端點：  

```
aws iot describe-endpoint --endpoint-type IOT:Data-ATS
```

thingName  
影子所屬物件物件的名稱

shadowName  
已命名影子的名稱。此參數不會與未命名影子搭配使用。

## 在連線至 時初始化應用程式或服務 AWS IoT
<a name="device-shadow-comms-app-first-connect"></a>

當應用程式第一次連線到 時 AWS IoT，應傳送 HTTP GET 請求至其使用的影子 URLs，以取得其使用的影子目前狀態。這可讓它將應用程式或服務同步到影子。

## 應用程式或服務連線到 時，處理狀態會變更 AWS IoT
<a name="device-shadow-comms-app-while-connected"></a>

當應用程式或服務連線到 時 AWS IoT，它可以在其使用的影子 URLs上傳送 HTTP GET 請求，以定期查詢目前狀態。

當使用者與應用程式或服務互動以變更裝置狀態時，應用程式或服務可以將 HTTP POST 請求傳送至用來更新 `desired` 影子狀態的影子 URL。此請求會傳回已接受的變更，但是您可能必須透過提出 HTTP GET 請求來輪詢影子，直到裝置已更新其新狀態的影子。

## 偵測裝置是否已連線
<a name="thing-connection"></a>

若要判斷裝置目前是否已連線，請在影子文件中包含 `connected` 屬性，並使用 MQTT Last Will 和 Testament (LWT) 訊息以將 `connected` 屬性設為 `false` (若裝置因錯誤而中斷連線)。

**注意**  
 AWS IoT Device Shadow 服務會忽略傳送至 AWS IoT 預留主題 （開頭為 \$1 的主題） 的 MQTT LWT 訊息。不過，它們是由訂閱的用戶端和 AWS IoT 規則引擎處理，因此您需要建立傳送至非預留主題的 LWT 訊息，以及將 MQTT LWT 訊息作為影子更新訊息重新發佈至影子的預留更新主題 的規則`ShadowTopicPrefix/update`。

**傳送 LWT 訊息 Device Shadow 服務**

1. 建立重新發佈保留主題上的 MQTT LWT 訊息的規則。下列範例規則會接聽有關 `my/things/myLightBulb/update` 主題的訊息，並將其重新發佈至 `$aws/things/myLightBulb/shadow/update`。

   ```
   {
       "rule": {
       "ruleDisabled": false,
       "sql": "SELECT * FROM 'my/things/myLightBulb/update'",
       "description": "Turn my/things/ into $aws/things/",
       "actions": [
           {
           "republish": {
               "topic": "$$aws/things/myLightBulb/shadow/update",
               "roleArn": "arn:aws:iam:123456789012:role/aws_iot_republish"
               }
           }
        ]
      }
   }
   ```

1. 當裝置連線到 時 AWS IoT，它會將 LWT 訊息註冊到未保留的主題，以便重新發佈規則進行辨識。在此範例中，該主題是 `my/things/myLightBulb/update`，它會將連線的內容設定為 `false`。

   ```
   {
       "state": {        
           "reported": {
               "connected":"false"
           }
       }
   }
   ```

1. 連線後，裝置會在其影子更新主題上發佈訊息 `$aws/things/myLightBulb/shadow/update`，並報告其目前狀態，其中包括將其 `connected` 屬性設定為 `true`。

   ```
   {
        "state": {        
           "reported": {
               "connected":"true"
           }
       }
   }
   ```

1. 在裝置正常中斷連線之前，它會發佈其影子更新主題的訊息 `$aws/things/myLightBulb/shadow/update`，以報告其最新狀態，其中包括將其 `connected` 屬性設定為 `false`。

   ```
   {
       "state": {        
           "reported": {
               "connected":"false"
           }
       }
   }
   ```

1. 如果裝置因錯誤而中斷連線， AWS IoT 訊息中介裝置會代表裝置發佈裝置的 LWT 訊息。重新發佈規則會偵測到此訊息，並發佈影子更新訊息，以更新 Device Shadow 的 `connected` 屬性。

**注意**  
由於中斷連線處理的非同步性質，無法保證在重新連線期間依順序分派 LWT 訊息。我們建議您使用[生命週期事件](life-cycle-events.md)來改善連線狀態偵測的準確性，因為這些事件提供屬性來管理out-of-order的事件。