

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

# 教學課程：重新發佈 MQTT 訊息
<a name="iot-repub-rule"></a>

本教學課程示範如何建立 AWS IoT 規則，在接收到指定的 MQTT 訊息時發佈 MQTT 訊息。傳入的訊息承載可在發佈前由規則進行修改。這樣就可以建立專為特定應用程式量身訂製的訊息，而不需要更改裝置或其韌體。您還可使用規則的篩選條件面向，僅在符合特定條件時才發佈訊息。

規則重新發佈的訊息就像由任何其他 AWS IoT 裝置或用戶端傳送的訊息。裝置可訂閱重新發佈的訊息，就像裝置可訂閱任何其他 MQTT 訊息主題一樣。

**您會在本教學課程中學到什麼：**
+ 如何在規則查詢陳述式中使用簡單的 SQL 查詢和函數
+ 如何使用 MQTT 用戶端測試 AWS IoT 規則

此教學課程約需 30 分鐘方能完成。

**Topics**
+ [檢閱 MQTT 主題和 AWS IoT 規則](#iot-repub-rule-mqtt)
+ [步驟 1：建立 AWS IoT 規則以重新發佈 MQTT 訊息](#iot-repub-rule-define)
+ [步驟 2：測試新規則](#iot-repub-rule-test)
+ [步驟 3：檢閱結果及後續步驟](#iot-repub-rule-review)

**開始本教學課程之前，請確定您有：**
+ 

**[設定 AWS 帳戶](setting-up.md)**  
您需要 AWS 帳戶 和 AWS IoT 主控台才能完成本教學課程。
+ 

**檢閱 [使用 MQTT 用戶端檢視 AWS IoT MQTT 訊息](view-mqtt-messages.md)**  
請確定您可使用 MQTT 用戶端來訂閱並發佈至主題。您會使用 MQTT 用戶端，在此程序中測試您的新規則。

## 檢閱 MQTT 主題和 AWS IoT 規則
<a name="iot-repub-rule-mqtt"></a>

在討論 AWS IoT 規則之前，了解 MQTT 通訊協定會有幫助。在 IoT 解決方案中，MQTT 通訊協定提供了一些優於其他網路通訊協定 (如 HTTP) 的優勢，這使其成為 IoT 裝置使用的熱門選擇。本節將會檢視 MQTT 適用於本教學課程的主要層面。如需 MQTT 與 HTTP 比較的資訊，請參閱 [選擇裝置通訊的應用程式通訊協定](protocols.md#protocol-selection)。

**MQTT 通訊協定**  
MQTT 通訊協定會與其主機一起使用發佈/訂閱通訊模型。若要傳送資料，裝置會將主題識別的訊息發佈至 AWS IoT 訊息中介裝置。若要收到訊息代理程式的訊息，裝置會在訂閱請求中傳送主題篩選條件給訊息代理程式，以訂閱其會收到的主題。 AWS IoT 規則引擎會收到來自訊息代理程式的 MQTT 訊息。

**AWS IoT 規則**  
AWS IoT 規則包含規則查詢陳述式和一或多個規則動作。當 AWS IoT 規則引擎收到 MQTT 訊息時，這些元素對訊息產生的作用如下。
+ 

**規則查詢陳述式**  
規則的查詢陳述式說明要使用的 MQTT 主題、解譯來自訊息承載的資料，及依據 SQL 陳述式所描述的 SQL 陳述式來格式化資料，這些陳述式類似於常用 SQL 資料庫所使用的陳述式。查詢陳述式的結果為傳送至規則動作的資料。
+ 

**規則動作**  
規則中的每個規則動作都會作用於規則查詢陳述式所產生的資料。 AWS IoT 支援[許多規則動作](iot-rule-actions.md)。不過，在本教學課程中，您會專注於 [重新發佈](republish-rule-action.md) 規則動作，其會將查詢陳述式的結果發佈為具有特定主題的 MQTT 訊息。

## 步驟 1：建立 AWS IoT 規則以重新發佈 MQTT 訊息
<a name="iot-repub-rule-define"></a>

您將在本教學課程中建立的 AWS IoT 規則會訂閱 `device/device_id/data` MQTT 主題，其中 *device\$1id* 是傳送訊息的裝置 ID。[主題篩選條件](topics.md#topicfilters)會將這些主題描述為 `device/+/data`，其中`+` 為與兩個正斜線字元間之任何字串相符的萬用字元。

規則收到來自相符主題的訊息時，其會重新發佈 `device_id` 和 `temperature` 值，作為具 `device/data/temp` 主題的新 MQTT 訊息。

例如，具 `device/22/data` 主題的 MQTT 訊息承載如下所示：

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

該規則採用來自訊息承載的 `temperature` 值及來自主題的 `device_id`，並將其重新發佈為具 `device/data/temp` 主題的 MQTT 訊息，及如下所示的訊息承載：

```
{
  "device_id": "22",
  "temperature": 28
}
```

使用此規則，則只需要裝置 ID 和溫度資料的裝置會訂閱 `device/data/temp` 主題，以僅接收該資訊。

**如要建立一個重新發佈 MQTT 訊息的規則**

1. 開啟 [AWS IoT 主控台的**規則**中樞](https://console.aws.amazon.com//iot/home#/rulehub)。

1. 在 **Rules** (規則) 中，選擇**Create**(建立)，然後開始建立新規則。

1. 在 **Create a rule** (建立規則) 的頂部中：

   1. 在 **Name** (名稱) 中，輸入規則的名稱。在本教學課程中，請將其命名為 **republish\$1temp**。

      請記住，規則名稱在您的帳戶和區域內必須是唯一的，且不能有任何空格。我們在此名稱中使用底線字元來分隔規則名稱中的兩個單字。

   1.  在 **Description** (說明) 中，說明規則。

      有意義的說明可幫助您記住此規則的作用及建立規則的原因。說明可依所需而定，因此請盡可能詳細說明。

1. 在 **Create a rule** (建立規則) 的 **Rule query statement** (規則查詢陳述式) 中：

   1.  在**使用 SQL 版本**中，選取 **2016-03-23**。

   1. 在 **Rule query statement** (規則查詢陳述式) 編輯方塊中輸入陳述式：

      ```
      SELECT topic(2) as device_id, temperature FROM 'device/+/data'
      ```

      本陳述式：
      + 聆聽具與 `device/+/data` 主題篩選條件相符之主題的 MQTT 訊息。
      + 從主題字串中選取第二個元素，並將其指定給 `device_id` 欄位。
      + 從訊息承載選取值 `temperature` 欄位，並將其指派給 `temperature` 欄位。

1. 在 **Set one or more actions** (設定一個或多個動作) 中：

   1. 若要開啟此規則的規則動作清單，請選擇 **Add action** (新增動作)。

   1. 在**選取動作**中，選擇**重新發佈訊息至 AWS IoT 主題**。

   1. 在動作清單底部，選擇**設定動作**以開啟所選動作的組態頁面。

1. 在 **Configure action** (設定動作)：

   1.  在 **Topic** (主題) 中，輸入 **device/data/temp**。這是此規則將發佈訊息的 MQTT 主題。

   1.  在**Quality of Service** (服務品質) 中，選擇 **0 - The message is delivered zero or more times** (0 - 訊息傳遞零次或多次)。

   1.  在**選擇或建立角色以授予執行此動作的 AWS IoT 存取權**：

      1.  選擇 **Create Role** (建立角色)。**Create a new role** (建立新角色) 對話方塊隨即開啟。

      1. 輸入可說明新角色的名稱。在本教學課程中，使用 **republish\$1role**。

         當您建立新角色時，會建立執行規則動作的正確政策，並將其連接至新角色。如果您變更此規則動作的主題，或在其他規則動作中使用此角色，則必須更新該角色的政策，以授權新的主題或動作。若要更新現有角色，請選擇本節中的 **Update role** (更新角色)。

      1. 選擇**Create Role** (建立角色)，以建立角色並關閉對話方塊。

   1. 選擇**Add action** (新增動作)，將動作新增至規則，並返回**Create a rule** (建立規則) 頁面。

1. 將**訊息重新發佈至 AWS IoT 主題**動作現在列在**設定一或多個動作**中。

   在新動作的圖標中，**Republish a message to an AWS IoT topic (將訊息重新發佈至 IoT 主題)** 之下，您可看到重新發佈動作將發佈的主題。

   這是您將新增至此規則的唯一規則動作。

1. 在 **Create a rule** (建立規則) 中，向下捲動至底部，然後選擇 **Create rule** (建立規則)，建立規則並完成此步驟。

## 步驟 2：測試新規則
<a name="iot-repub-rule-test"></a>

若要測試新規則，您將使用 MQTT 用戶端來發佈和訂閱此規則所使用的 MQTT 訊息。

在新視窗的 [AWS IoT 主控台中開啟 MQTT 用戶端](https://console.aws.amazon.com//iot/home#/test)。這可讓您編輯規則，而不會遺失 MQTT 用戶端的組態。如果您讓它轉到主控台中的另一個頁面，MQTT 用戶端不會保留任何訂閱或訊息記錄。

**如要使用 MQTT 用戶端來測試您的規則。**

1. 在 AWS IoT 主控台的 [MQTT 用戶端](https://console.aws.amazon.com//iot/home#/test) 中，訂閱輸入主題，在此案例中為 `device/+/data`。

   1. 在 MQTT 用戶端中的 **Subscriptions** (訂閱) 下選擇 **Subscribe to a topic** (訂閱主題)。

   1. 在 **Subscription topic** (訂閱主題) 中，輸入輸入主題篩選條件 **device/\$1/data** 的主題 。

   1. 將剩下的欄位保留為其預設設定。

   1. 請選擇 **Subscribe to topic** (訂閱主題)。

      在 **Subscriptions** (訂閱) 欄中，**Publish to a topic** (發佈到主題) 之下，**device/\$1/data** 隨即顯示。

1. 訂閱規則將發佈的主題：`device/data/temp`。

   1. 在 **Subscriptions** (訂閱) 之下，選擇 **Subscribe to a topic** (訂閱主題)，並在 **Subscription topic** (訂閱主題) 中，輸入重新發佈訊息 **device/data/temp** 的主題。

   1. 將剩下的欄位保留為其預設設定。

   1. 請選擇 **Subscribe to topic** (訂閱主題)。

      在 **Subscriptions** (訂閱) 欄中，**device/\$1/data** 之下，**device/data/temp** 隨即顯示。

1. 使用特定裝置 ID **device/22/data**，將訊息發佈至輸入主題。您無法發佈至包含萬用字元的 MQTT 主題。

   1. 在 MQTT 用戶端中的 **Subscriptions** (訂閱) 下選擇 **Publish to topic** (發佈至主題)。

   1. 在 **Publish** (發佈) 欄位中輸入輸入主題名稱 **device/22/data**。

   1. 複製此處顯示的範例資料，並在主題名稱下方的編輯方塊中貼上範例資料。

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. 若要傳送 MQTT 訊息，請選擇 **Publish to topic** (發佈至主題)。

1. 檢閱傳送的訊息。

   1. 在 MQTT 用戶端中的 **Subscriptions** (訂閱) 下，您先前訂閱的兩個主題旁會有一個綠點。

      該綠點表示自上次查看後，已收到一個或多個新訊息。

   1. 於 **Subscriptions** (訂閱) 下，選擇 **device/\$1/data**，來檢查訊息承載是否與您剛剛發佈的內容相符，如下所示：

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. 於 **Subscriptions** (訂閱) 下，選擇 **device/data/temp**，來檢查您重新發佈的訊息承載，如下所示：

      ```
      {
        "device_id": "22",  
        "temperature": 28
      }
      ```

      請注意，`device_id` 值是個帶有引號的字串，而 `temperature` 值是個數字。這是因為 [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic) 函數從輸入訊息的主題名稱中提取字串，而 `temperature` 值會使用輸入訊息承載的數值。

      若要將 `device_id` 值設為數值，請將規則查詢陳述式中的 `topic(2)` 替換為：

      ```
      cast(topic(2) AS DECIMAL)
      ```

      請注意，將 `topic(2)` 值轉換為數值，僅適用於主題的該部分僅包含數字字元時。

1. 若您看到正確的訊息已發佈至 **device/data/temp** 主題，則您的規則有效。請參閱下一節，了解更多 Republish (重新發佈) 規則動作的相關資訊。

   若您看不到正確的訊息已發佈至 **device/\$1/data** 或 **device/data/temp** 主題中，請查看疑難排解提示。

### 疑難排解重新發佈訊息規則
<a name="iot-repub-rule-trouble"></a>

若您並未看到預期的結果，請查看以下事項。
+ 

**您收到錯誤的橫幅**  
若在您發佈輸入訊息時出現錯誤，請先更正該錯誤。下列步驟可協助您修正該錯誤。
+ 

**您並未在 MQTT 用戶端中看到輸入訊息**  
每次您將輸入訊息發佈至 `device/22/data` 主題時，若您依程序中所述訂閱了 `device/+/data` 主題篩選條件，則該訊息應會顯示於 MQTT 用戶端中。

**要檢查的事項**
  + 

**檢查您訂閱的主題篩選條件**  
若您依程序中所述訂閱了輸入訊息主題，則每次發佈輸入訊息時都應該會看到其複本。

    若您並未訊息，請檢查您訂閱的主題名稱，並將其與所發佈的主題進行比較。主題名稱區分大小寫，且您訂閱的主題必須與所發佈訊息承載的主題相同。
  + 

**檢查訊息發佈功能**  
在 MQTT 用戶端中的 **Subscriptions** (訂閱) 下，選擇 **device/\$1/data**，檢查發佈訊息的主題，然後選擇 **Publish to topic** (發佈至主題)。您應該會在訊息清單中出現主題下方的編輯方塊中看到訊息承載。
+ 

**您在 MQTT 用戶端中並未看到已重新發佈的訊息**  
若要讓您的規則運作，其必須具有授權其接收和重新發佈訊息的正確政策，且必須接收訊息。

**要檢查的事項**
  + 

**檢查 MQTT 用戶端 AWS 區域 的 和您建立的規則**  
您正在執行 MQTT 用戶端的主控台必須與您建立的規則處於相同的 AWS 區域。
  + 

**檢查規則查詢陳述式中的輸入訊息主題**  
若要讓規則運作，其必須收到一則訊息，其主題名稱與規則查詢陳述式之 FROM 子句中的主題篩選條件相符。

    檢查規則查詢陳述式中主題篩選條件的拼字與 MQTT 用戶端中主題的拼字。主題名稱區分大小寫，且郵件的主題必須與規則查詢陳述式中的主題篩選條件相符。
  + 

**檢查輸入訊息承載的內容**  
若要讓規則運作，其必須在 SELECT 陳述式中宣告的訊息承載中尋找資料欄位。

    檢查規則查詢陳述式中 `temperature` 欄位的拼字與 MQTT 用戶端中訊息承載的拼字。欄位名稱區分大小寫，規則查詢陳述式中的 `temperature` 欄位必須與訊息承載中的 `temperature` 欄位相符。

    請確定訊息承載中的 JSON 文件格式正確。若 JSON 有任何錯誤，例如缺少逗號，則規則將無法進行讀取。
  + 

**檢查規則動作中重新發佈的訊息主題**  
Republish (重新發佈) 規則動作發佈新訊息的主題必須與您在 MQTT 用戶端中訂閱的主題相符。

    開啟您建立於主控台中的規則，並檢查規則動作重新發佈訊息的主題。
  + 

**檢查規則所使用的角色**  
規則動作必須具有接收原始主題及發佈新主題的權限。

    授權規則接收訊息資料的政策並加以重新發佈為所使用的主題所特定的。若變更用於重新發佈訊息資料的主題，則必須更新規則動作的角色，來更新其政策以與目前主題相符。

    若您懷疑這會是問題，請編輯 Republish (重新發佈) 規則動作並建立新角色。規則動作建立的新角色會收到執行這些動作所需的授權。

## 步驟 3：檢閱結果及後續步驟
<a name="iot-repub-rule-review"></a>

**於本教學課程中**
+ 您使用了簡單的 SQL 查詢和規則查詢陳述式中的幾個函數來產生一個新的 MQTT 訊息。
+ 您已建立一個重新發佈該新訊息的規則。
+ 您使用 MQTT 用戶端來測試 AWS IoT 規則。

**後續步驟**  
使用此規則重新發佈一些訊息之後，請嘗試使用其來查看教學課程的某些層面如何影響重新發佈的訊息。此處有幾種簡單的入門方式。
+ 變更輸入訊息主題中的 *device\$1id*，並觀察重新發佈之訊息承載中的影響。
+ 變更規則查詢陳述式中所選取的欄位，並觀察重新發佈之訊息承載中的影響。
+ 請嘗試本系列中的下一個教學課程，並了解如何進行 [教學課程：傳送 Amazon SNS 通知](iot-sns-rule.md)。

此教學課程中所使用的 Republish (重新發佈) 規則動作亦可協助您對規則查詢陳述式進行偵錯。例如，您可將此動作新增至規則，以查看其規則查詢陳述式如何格式化用於其規則動作的資料。