

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

# Connect 客户端设备与核心设备连接
<a name="connect-client-devices"></a>

您可以将*云发现*配置为将客户端设备连接到核心设备。配置云发现时，客户端设备可以连接到 AWS IoT Greengrass 云服务，以检索有关其可以连接的核心设备的信息。然后，客户端设备可以尝试连接到每台核心设备，直至其成功连接。

要使用云发现，您必须执行以下操作：
+ 将客户端设备与其可以连接的核心设备关联。
+ 指定客户端设备可以连接到每个核心设备的 MQTT 代理端点。
+ 将组件部署到能启用客户端设备支持的核心设备。

  您也可以部署可选组件来执行以下操作：
  + 在客户端设备、Greengrass 组件和云服务之间中继消息。 AWS IoT Core 
  + 自动为您管理核心设备 MQTT 代理端点。
  + 管理本地客户端设备阴影并将阴影与 AWS IoT Core 云服务同步。

您还必须查看并更新核心设备的 AWS IoT 策略，以验证其是否具有连接客户端设备所需的权限。有关更多信息，请参阅 [要求](#connect-client-devices-requirements)。

配置云发现后，您可以测试客户端设备与核心设备间的通信。有关更多信息，请参阅[测试客户端设备通信](test-client-device-communications.md)。

**Topics**
+ [要求](#connect-client-devices-requirements)
+ [用于支持客户端设备的 Greengrass 组件](#cloud-discovery-components)
+ [配置云发现（控制台）](#configure-cloud-discovery-console)
+ [配置云发现（AWS CLI）](#configure-cloud-discovery-cli)
+ [关联客户端设备](associate-client-devices.md)
+ [在离线时对客户端进行身份验证](offline-authentication.md)
+ [管理核心设备端点](manage-core-device-endpoints.md)
+ [选择 MQTT 代理](choose-local-mqtt-broker.md)
+ [使用 MQTT 代理将客户端设备连接到 AWS IoT Greengrass 核心设备](connecting-to-mqtt.md)
+ [测试客户端设备通信](test-client-device-communications.md)
+ [Greengrass 发现 API RESTful](greengrass-discover-api.md)

## 要求
<a name="connect-client-devices-requirements"></a>

要将客户端设备连接到核心设备，您必须满足以下要求或具备以下内容：
+ 核心设备必须运行 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.2.0 或更高版本。
+ 在核心设备运行的区域， AWS IoT Greengrass 与 AWS 账户 您关联的 Greengrass 服务角色。 AWS 有关更多信息，请参阅 [配置 Greengrass 服务角色](#configure-service-role-requirement)。
+ 核心设备的 AWS IoT 策略必须允许以下权限：<a name="core-device-iot-policy-client-device-permissions"></a>
  + <a name="core-device-iot-policy-client-device-permissions-putcertificateauthorities"></a>`greengrass:PutCertificateAuthorities`
  + <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceidentity"></a>`greengrass:VerifyClientDeviceIdentity`
  + <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceiotcertificateassociation"></a>`greengrass:VerifyClientDeviceIoTCertificateAssociation`
  + <a name="core-device-iot-policy-client-device-permissions-getconnectivityinfo"></a>`greengrass:GetConnectivityInfo`
  + <a name="core-device-iot-policy-client-device-permissions-updateconnectivityinfo"></a>`greengrass:UpdateConnectivityInfo`—（可选）使用 [IP 检测器组件需要此权限，该组件](ip-detector-component.md)将核心设备的网络连接信息报告给 AWS IoT Greengrass 云服务。
  + <a name="core-device-iot-policy-client-device-permissions-shadows"></a>`iot:GetThingShadow``iot:UpdateThingShadow`、和 `iot:DeleteThingShadow` —（可选）使用[影子管理器组件与客户端设备影子](shadow-manager-component.md)同步需要这些权限 AWS IoT Core。此功能需要 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.6.0 或更高版本、影子管理器 v2.2.0 或更高版本以及 [MQTT 网桥](mqtt-bridge-component.md) v2.2.0 或更高版本。

  有关更多信息，请参阅 [配置 AWS IoT 事物策略](#configure-iot-policy-requirement)。
**注意**  
如果您在[安装 AWS IoT Greengrass 酷睿软件](install-greengrass-core-v2.md)时使用默认 AWS IoT 策略，则核心设备具有允许访问所有 AWS IoT Greengrass 操作的 AWS IoT 策略（`greengrass:*`）。
+ AWS IoT 可以作为客户端设备连接的东西。有关更多信息，请参阅《AWS IoT Core 开发人员指南》**中的[创建 AWS IoT 资源](https://docs.aws.amazon.com/iot/latest/developerguide/create-iot-resources.html)。
+ 客户端设备必须使用客户端 ID 进行连接。客户端 ID 是一个事物名称。不接受其他客户端 ID。
+ 每台客户端设备的 AWS IoT 策略都必须允许该`greengrass:Discover`权限。有关更多信息，请参阅 [客户端设备的最低 AWS IoT 政策](device-auth.md#client-device-minimal-iot-policy)。

**Topics**
+ [配置 Greengrass 服务角色](#configure-service-role-requirement)
+ [配置 AWS IoT 事物策略](#configure-iot-policy-requirement)

### 配置 Greengrass 服务角色
<a name="configure-service-role-requirement"></a>

<a name="greengrass-service-role-intro"></a>Greengrass 服务角色 AWS Identity and Access Management 是一个 (IAM) 服务角色，它 AWS IoT Greengrass 授权代表您访问服务中的资源。 AWS 此角色 AWS IoT Greengrass 使验证客户端设备的身份和管理核心设备的连接信息成为可能。

如果您之前未在该区域设置 [Greengrass 服务角色，则必须将该区域的 Green](greengrass-service-role.md) grass 服务角色与您的服务角色相关联。 AWS IoT Greengrass AWS 账户 

在[AWS IoT Greengrass 控制台](https://console.aws.amazon.com/greengrass)中使用**配置核心设备发现**页面时，请为您 AWS IoT Greengrass 设置 Greengrass 服务角色。否则，您可以使用[AWS IoT 控制台](https://console.aws.amazon.com/iot)或 AWS IoT Greengrass API 进行手动设置。

在本节中，您将检查是否已设置好 Greengrass 服务角色。如果未设置，则可以在该区域为您创建一个新的 Greengrass 服务角色 AWS IoT Greengrass 进行关联。 AWS 账户 

#### 配置 Greengrass 服务角色（控制台）
<a name="configure-service-role-requirement-console"></a>

1. 检查该区域中是否与您的 Greengrass 服务角色相关 AWS IoT Greengrass 联。 AWS 账户 执行以下操作：

   1. <a name="open-iot-console"></a>导航至 [AWS IoT 控制台](https://console.aws.amazon.com/iot)。

   1. 在导航窗格中，选择**设置**。

   1. 在 **Greengrass 服务角色**部分，找到**当前服务角色**以查看是否关联了 Greengrass 服务角色。

      如果您关联了 Greengrass 服务角色，则符合使用 IP 检测器组件的要求。跳至[配置 AWS IoT 事物策略](#configure-iot-policy-requirement)。

1. 如果该区域中没有 AWS IoT Greengrass 与您的 Greengrass 服务角色关联， AWS 账户 请创建一个 Greengrass 服务角色并将其关联。执行以下操作：

   1. 导航到 [IAM 控制台](https://console.aws.amazon.com/iam)。

   1. 选择**角色**。

   1. 选择**创建角色**。

   1. 在**创建角色**页面上，执行以下操作：

      1. 在**可信实体类型**下，选择 **AWS 服务**。

      1. 在**使用案例**、**其他 AWS 服务使用案例**下，选择 **Greengrass**，然后选择 **Greengrass**。此选项指定添加为可以 AWS IoT Greengrass 担任此角色的可信实体。

      1. 选择**下一步**。

      1. 在**权限策略**下，选择要附加到角色的 **AWSGreengrassResourceAccessRolePolicy**。

      1. 选择**下一步**。

      1. 在**角色名称**中，输入角色的名称，例如 **Greengrass\$1ServiceRole**。

      1. 选择**创建角色**。

   1. <a name="open-iot-console"></a>导航至 [AWS IoT 控制台](https://console.aws.amazon.com/iot)。

   1. 在导航窗格中，选择**设置**。

   1. 在 **Greengrass 服务角色**部分，选择**附加角色**。

   1. 在**更新 Greengrass 服务角色**模式中，选择您创建的 IAM 角色，然后选择**附加角色**。

#### 配置 Greengrass 服务角色（AWS CLI）
<a name="configure-service-role-requirement-cli"></a>

1. 检查该区域中是否与您的 Greengrass 服务角色相关 AWS IoT Greengrass 联。 AWS 账户 

   ```
   aws greengrassv2 get-service-role-for-account
   ```

   如果关联了 Greengrass 服务角色，则该操作会返回包含有关该角色的信息的响应。

   如果您关联了 Greengrass 服务角色，则符合使用 IP 检测器组件的要求。跳至[配置 AWS IoT 事物策略](#configure-iot-policy-requirement)。

1. 如果该区域中没有 AWS IoT Greengrass 与您的 Greengrass 服务角色关联， AWS 账户 请创建一个 Greengrass 服务角色并将其关联。执行以下操作：

   1. <a name="create-greengrass-service-role-step-create-role"></a>使用允许代入该角色 AWS IoT Greengrass 的信任策略创建角色。此示例将创建一个名为 `Greengrass_ServiceRole` 的角色，但您也可以使用其他名称。我们建议您在信任策略中加入 `aws:SourceArn` 和 `aws:SourceAccount` 全局条件上下文键，以帮助防止出现*混淆代理人*安全问题。条件上下文键可限制访问权限，仅允许来自指定账户和 Greengrass 工作空间的请求。有关混淆代理人问题的更多信息，请参阅 [防止跨服务混淆代理](cross-service-confused-deputy-prevention.md)。

------
#### [ Linux or Unix ]

      ```
      aws iam create-role --role-name Greengrass_ServiceRole --assume-role-policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "greengrass.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
              "ArnLike": {
                "aws:SourceArn": "arn:aws:greengrass:region:account-id:*"
              },
              "StringEquals": {
                "aws:SourceAccount": "account-id"
              }
            }
          }
        ]
      }'
      ```

------
#### [ Windows Command Prompt (CMD) ]

      ```
      aws iam create-role --role-name Greengrass_ServiceRole --assume-role-policy-document "{\\"Version\\":\\"2012-10-17		 	 	 \\",\\"Statement\\":[{\\"Effect\\":\\"Allow\\",\\"Principal\\":{\\"Service\\":\\"greengrass.amazonaws.com\\"},\\"Action\\":\\"sts:AssumeRole\\",\\"Condition\\":{\\"ArnLike\\":{\\"aws:SourceArn\\":\\"arn:aws:greengrass:region:account-id:*\\"},\\"StringEquals\\":{\\"aws:SourceAccount\\":\\"account-id\\"}}}]}"
      ```

------
#### [ PowerShell ]

      ```
      aws iam create-role --role-name Greengrass_ServiceRole --assume-role-policy-document '{
        "Version": "2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "greengrass.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
              "ArnLike": {
                "aws:SourceArn": "arn:aws:greengrass:region:account-id:*"
              },
              "StringEquals": {
                "aws:SourceAccount": "account-id"
              }
            }
          }
        ]
      }'
      ```

------

   1. <a name="create-greengrass-service-role-step-copy-role-arn"></a>从输出中的角色元数据复制角色 ARN。使用该 ARN 将角色与您的账户关联。

   1. <a name="create-greengrass-service-role-step-attach-policy"></a>将 `AWSGreengrassResourceAccessRolePolicy` 策略附加到该角色。

      ```
      aws iam attach-role-policy --role-name Greengrass_ServiceRole --policy-arn arn:aws:iam::aws:policy/service-role/AWSGreengrassResourceAccessRolePolicy
      ```

   1. 将 Greengrass 服务角色与您的服务角色相关联。 AWS IoT Greengrass AWS 账户*role-arn*替换为服务角色的 ARN。

      ```
      aws greengrassv2 associate-service-role-to-account --role-arn role-arn
      ```

      如果操作成功，将返回以下响应。

      ```
      {
        "associatedAt": "timestamp"
      }
      ```

### 配置 AWS IoT 事物策略
<a name="configure-iot-policy-requirement"></a>

核心设备使用 X.509 设备证书来授权与 AWS的连接。您可以将 AWS IoT 策略附加到设备证书以定义核心设备的权限。有关更多信息，请参阅[AWS IoT 数据平面操作策略](device-auth.md#iot-policies)和[支持客户端设备的最低 AWS IoT 政策](device-auth.md#client-device-support-minimal-iot-policy)。

要将客户端设备连接到核心设备，核心设备的 AWS IoT 策略必须允许以下权限：<a name="core-device-iot-policy-client-device-permissions"></a>
+ <a name="core-device-iot-policy-client-device-permissions-putcertificateauthorities"></a>`greengrass:PutCertificateAuthorities`
+ <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceidentity"></a>`greengrass:VerifyClientDeviceIdentity`
+ <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceiotcertificateassociation"></a>`greengrass:VerifyClientDeviceIoTCertificateAssociation`
+ <a name="core-device-iot-policy-client-device-permissions-getconnectivityinfo"></a>`greengrass:GetConnectivityInfo`
+ <a name="core-device-iot-policy-client-device-permissions-updateconnectivityinfo"></a>`greengrass:UpdateConnectivityInfo`—（可选）使用 [IP 检测器组件需要此权限，该组件](ip-detector-component.md)将核心设备的网络连接信息报告给 AWS IoT Greengrass 云服务。
+ <a name="core-device-iot-policy-client-device-permissions-shadows"></a>`iot:GetThingShadow``iot:UpdateThingShadow`、和 `iot:DeleteThingShadow` —（可选）使用[影子管理器组件与客户端设备影子](shadow-manager-component.md)同步需要这些权限 AWS IoT Core。此功能需要 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.6.0 或更高版本、影子管理器 v2.2.0 或更高版本以及 [MQTT 网桥](mqtt-bridge-component.md) v2.2.0 或更高版本。

在本节中，您将查看核心设备的 AWS IoT 策略并添加缺少的所有必需权限。如果您使用[AWS IoT Greengrass 核心软件安装程序来配置资源](quick-installation.md)，则您的核心设备具有允许访问所有 AWS IoT Greengrass 操作的 AWS IoT 策略（`greengrass:*`）。在这种情况下，只有当您计划部署影子管理器组件来同步设备影子时，才必须更新 AWS IoT 策略 AWS IoT Core。否则，您可以跳过此部分。

#### 配置 AWS IoT 事物策略（控制台）
<a name="configure-iot-policy-requirement-console"></a>

1. <a name="update-iot-policy-console-open-greengrass-console"></a>在 [AWS IoT Greengrass 控制台](https://console.aws.amazon.com/greengrass)导航菜单中，选择**核心设备**。

1. <a name="update-iot-policy-console-choose-core-device"></a>在**核心设备**页面上，选择要更新的核心设备。

1. <a name="update-iot-policy-console-choose-core-device-thing"></a>在核心设备详细信息页面上，选择指向核心设备的**事物**的链接。此链接可打开 AWS IoT 控制台中的事物详细信息页面。

1. <a name="update-iot-policy-console-choose-thing-security"></a>在“事物详细信息”页面上，选择**证书**。

1. <a name="update-iot-policy-console-choose-thing-certificate"></a>在**证书**选项卡中，选择事物的有效证书。

1. <a name="update-iot-policy-console-choose-certificate-policies"></a>在证书详细信息页面上，选择**策略**。

1. <a name="update-iot-policy-console-choose-policy"></a>在 “**策略**” 选项卡中，选择要查看和更新的 AWS IoT 策略。您可以为附加到核心设备有效证书的任何策略添加所需权限。
**注意**  <a name="quick-installation-iot-policies-note"></a>
如果您使用[AWS IoT Greengrass 核心软件安装程序来配置资源](quick-installation.md)，则有两个 AWS IoT 策略。我们建议您选择名为 **GreengrassV2IoTThingPolicy** 的策略（如果存在）。默认情况下，使用快速安装程序创建的核心设备将使用此策略名称。如果您为此策略添加权限，则也会将这些权限授予使用此策略的其他核心设备。

1. <a name="update-iot-policy-console-edit-policy"></a>在策略概述中，选择**编辑活动版本**。

1. 查看策略以了解所需权限，然后添加缺失的所有必要权限。<a name="core-device-iot-policy-client-device-permissions"></a>
   + <a name="core-device-iot-policy-client-device-permissions-putcertificateauthorities"></a>`greengrass:PutCertificateAuthorities`
   + <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceidentity"></a>`greengrass:VerifyClientDeviceIdentity`
   + <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceiotcertificateassociation"></a>`greengrass:VerifyClientDeviceIoTCertificateAssociation`
   + <a name="core-device-iot-policy-client-device-permissions-getconnectivityinfo"></a>`greengrass:GetConnectivityInfo`
   + <a name="core-device-iot-policy-client-device-permissions-updateconnectivityinfo"></a>`greengrass:UpdateConnectivityInfo`—（可选）使用 [IP 检测器组件需要此权限，该组件](ip-detector-component.md)将核心设备的网络连接信息报告给 AWS IoT Greengrass 云服务。
   + <a name="core-device-iot-policy-client-device-permissions-shadows"></a>`iot:GetThingShadow``iot:UpdateThingShadow`、和 `iot:DeleteThingShadow` —（可选）使用[影子管理器组件与客户端设备影子](shadow-manager-component.md)同步需要这些权限 AWS IoT Core。此功能需要 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.6.0 或更高版本、影子管理器 v2.2.0 或更高版本以及 [MQTT 网桥](mqtt-bridge-component.md) v2.2.0 或更高版本。

1. （可选）要允许核心设备与其同步阴影 AWS IoT Core，请在策略中添加以下声明。如果您计划与客户端设备影子进行交互，但不打算与之同步 AWS IoT Core，请跳过此步骤。将*region*和*account-id*替换为您使用的地区和您的 AWS 账户 电话号码。
   + 此示例语句允许访问所有事物的设备影子。要遵循最佳安全实践，您可以将访问权限限制为仅访问核心设备和您连接到核心设备的客户端设备。有关更多信息，请参阅[支持客户端设备的最低 AWS IoT 政策](device-auth.md#client-device-support-minimal-iot-policy)。

   ```
   {
     "Effect": "Allow",
     "Action": [
       "iot:GetThingShadow",
       "iot:UpdateThingShadow",
       "iot:DeleteThingShadow"
     ],
     "Resource": [
       "arn:aws:iot:region:account-id:thing/*"
     ]
   }
   ```

   添加此语句后，策略文档可能看上去与以下示例相似。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "iot:Connect",
           "iot:Publish",
           "iot:Subscribe",
           "iot:Receive",
           "greengrass:*"
         ],
         "Resource": "*"
       },
       {
         "Effect": "Allow",
         "Action": [
           "iot:GetThingShadow",
           "iot:UpdateThingShadow",
           "iot:DeleteThingShadow"
         ],
         "Resource": [
           "arn:aws:iot:us-east-1:123456789012:thing/*"
         ]
       }
     ]
   }
   ```

------

1. <a name="update-iot-policy-console-set-as-active-version"></a>要将新的策略版本设置为活动版本，请在**策略版本状态**下，选择**将编辑后的版本设置为该策略的活动版本**。

1. <a name="update-iot-policy-console-save-policy"></a>选择**另存为新版本**。

#### 配置 AWS IoT 事物策略 (AWS CLI)
<a name="configure-iot-policy-requirement-cli"></a>

1. <a name="update-iot-policy-cli-list-thing-principals"></a>列出核心设备的原理 AWS IoT 。事物主体可以是 X.509 设备证书或其他标识。运行以下命令，并*MyGreengrassCore*替换为核心设备的名称。

   ```
   aws iot list-thing-principals --thing-name MyGreengrassCore
   ```

   该操作将返回一个响应，列出核心设备的事物主体。

   ```
   {
       "principals": [
           "arn:aws:iot:us-west-2:123456789012:cert/certificateId"
       ]
   }
   ```

1. <a name="update-iot-policy-cli-identify-active-certificate"></a>识别核心设备的有效证书。运行以下命令，并*certificateId*替换为上一步中每个证书的 ID，直到找到活动证书。证书 ID 是证书 ARN 末尾的十六进制字符串。`--query` 参数用于指定仅输出证书的状态。

   ```
   aws iot describe-certificate --certificate-id certificateId --query 'certificateDescription.status'
   ```

   该操作以字符串形式返回证书状态。例如，如果证书有效，则此操作会输出 `"ACTIVE"`。

1. <a name="update-iot-policy-cli-list-certificate-policies"></a>列出附加到证书的 AWS IoT 策略。运行以下命令，并将证书 ARN 替换为实际的证书 ARN。

   ```
   aws iot list-principal-policies --principal arn:aws:iot:us-west-2:123456789012:cert/certificateId
   ```

   该操作会返回一个响应，其中列出了附加到证书的 AWS IoT 策略。

   ```
   {
       "policies": [
           {
               "policyName": "GreengrassTESCertificatePolicyMyGreengrassCoreTokenExchangeRoleAlias",
               "policyArn": "arn:aws:iot:us-west-2:123456789012:policy/GreengrassTESCertificatePolicyMyGreengrassCoreTokenExchangeRoleAlias"
           },
           {
               "policyName": "GreengrassV2IoTThingPolicy",
               "policyArn": "arn:aws:iot:us-west-2:123456789012:policy/GreengrassV2IoTThingPolicy"
           }
       ]
   }
   ```

1. <a name="update-iot-policy-cli-choose-policy"></a>选择要查看和更新的策略。
**注意**  <a name="quick-installation-iot-policies-note"></a>
如果您使用[AWS IoT Greengrass 核心软件安装程序来配置资源](quick-installation.md)，则有两个 AWS IoT 策略。我们建议您选择名为 **GreengrassV2IoTThingPolicy** 的策略（如果存在）。默认情况下，使用快速安装程序创建的核心设备将使用此策略名称。如果您为此策略添加权限，则也会将这些权限授予使用此策略的其他核心设备。

1. <a name="update-iot-policy-cli-get-policy-document"></a>获取策略的文档。运行以下命令，并*GreengrassV2IoTThingPolicy*替换为策略的名称。

   ```
   aws iot get-policy --policy-name GreengrassV2IoTThingPolicy
   ```

   该操作会返回一个响应，其中包含策略的文档和有关该策略的其他信息。策略文档是一个序列化为字符串的 JSON 对象。

   ```
   {
       "policyName": "GreengrassV2IoTThingPolicy",
       "policyArn": "arn:aws:iot:us-west-2:123456789012:policy/GreengrassV2IoTThingPolicy",
       "policyDocument": "{\
     \\"Version\\": \\"2012-10-17		 	 	 \\",\
     \\"Statement\\": [\
       {\
         \\"Effect\\": \\"Allow\\",\
         \\"Action\\": [\
                   \\"iot:Connect\\",\
                   \\"iot:Publish\\",\
                   \\"iot:Subscribe\\",\
                   \\"iot:Receive\\",\
                   \\"greengrass:*\\"\
   ],\
         \\"Resource\\": \\"*\\"\
       }\
     ]\
   }",
       "defaultVersionId": "1",
       "creationDate": "2021-02-05T16:03:14.098000-08:00",
       "lastModifiedDate": "2021-02-05T16:03:14.098000-08:00",
       "generationId": "f19144b798534f52c619d44f771a354f1b957dfa2b850625d9f1d0fde530e75f"
   }
   ```

1. <a name="update-iot-policy-cli-create-policy-document-file"></a>使用在线转换器或其他工具将策略文档字符串转换为 JSON 对象，然后将其保存到名为 `iot-policy.json` 的文件中。

   例如，如果您安装了 [jq](https://stedolan.github.io/jq/) 工具，则可以运行以下命令来获取策略文档，将其转换为 JSON 对象，然后将策略文档另存为 JSON 对象。

   ```
   aws iot get-policy --policy-name GreengrassV2IoTThingPolicy --query 'policyDocument' | jq fromjson >> iot-policy.json
   ```

1. 查看策略以了解所需权限，然后添加缺失的所有必要权限。

   <a name="nano-command-intro-existing-file"></a>例如，在 Linux 系统上，您可以运行以下命令来使用 GNU nano 打开文件。

   ```
   nano iot-policy.json
   ```<a name="core-device-iot-policy-client-device-permissions"></a>
   + <a name="core-device-iot-policy-client-device-permissions-putcertificateauthorities"></a>`greengrass:PutCertificateAuthorities`
   + <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceidentity"></a>`greengrass:VerifyClientDeviceIdentity`
   + <a name="core-device-iot-policy-client-device-permissions-verifyclientdeviceiotcertificateassociation"></a>`greengrass:VerifyClientDeviceIoTCertificateAssociation`
   + <a name="core-device-iot-policy-client-device-permissions-getconnectivityinfo"></a>`greengrass:GetConnectivityInfo`
   + <a name="core-device-iot-policy-client-device-permissions-updateconnectivityinfo"></a>`greengrass:UpdateConnectivityInfo`—（可选）使用 [IP 检测器组件需要此权限，该组件](ip-detector-component.md)将核心设备的网络连接信息报告给 AWS IoT Greengrass 云服务。
   + <a name="core-device-iot-policy-client-device-permissions-shadows"></a>`iot:GetThingShadow``iot:UpdateThingShadow`、和 `iot:DeleteThingShadow` —（可选）使用[影子管理器组件与客户端设备影子](shadow-manager-component.md)同步需要这些权限 AWS IoT Core。此功能需要 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.6.0 或更高版本、影子管理器 v2.2.0 或更高版本以及 [MQTT 网桥](mqtt-bridge-component.md) v2.2.0 或更高版本。

1. <a name="update-iot-policy-cli-create-policy-version"></a>将更改保存为策略的新版本。运行以下命令，并*GreengrassV2IoTThingPolicy*替换为策略的名称。

   ```
   aws iot create-policy-version --policy-name GreengrassV2IoTThingPolicy --policy-document file://iot-policy.json --set-as-default
   ```

   如果操作成功，它会返回与以下示例类似的响应。

   ```
   {
       "policyArn": "arn:aws:iot:us-west-2:123456789012:policy/GreengrassV2IoTThingPolicy",
       "policyDocument": "{\
     \\"Version\\": \\"2012-10-17		 	 	 \\",\
     \\"Statement\\": [\
       {\
         \\"Effect\\": \\"Allow\\",\
         \\"Action\\": [\
   \\t\\t\\"iot:Connect\\",\
   \\t\\t\\"iot:Publish\\",\
   \\t\\t\\"iot:Subscribe\\",\
   \\t\\t\\"iot:Receive\\",\
   \\t\\t\\"greengrass:*\\"\
         ],\
         \\"Resource\\": \\"*\\"\
       }\
     ]\
   }",
       "policyVersionId": "2",
       "isDefaultVersion": true
   }
   ```

## 用于支持客户端设备的 Greengrass 组件
<a name="cloud-discovery-components"></a>

**重要**  <a name="client-device-support-nucleus-requirement"></a>
核心设备必须运行 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.2.0 或更高版本才能支持客户端设备。

要使客户端设备能够连接到核心设备并与之通信，请将以下 Greengrass 组件部署到核心设备：
+ <a name="client-device-component-overview-client-device-auth"></a>[客户端设备身份验证](client-device-auth-component.md) (`aws.greengrass.clientdevices.Auth`)

  部署客户端设备身份验证组件，以对客户端设备进行身份验证并授权客户端设备操作。这个组件允许你的 AWS IoT 东西连接到核心设备。

  此组件需要进行一些配置才能使用。您必须指定客户端设备组以及每个组有权执行的操作，例如通过 MQTT 进行连接和通信。有关更多信息，请参阅[客户端设备身份验证组件配置](client-device-auth-component.md#client-device-auth-component-configuration)。
+ <a name="client-device-component-overview-mqtt-broker-moquette"></a>[MQTT 3.1.1 代理（Moquette）](mqtt-broker-moquette-component.md) (`aws.greengrass.clientdevices.mqtt.Moquette`)

  部署 Moquette MQTT 代理组件来运行轻量级 MQTT 代理。Moquette MQTT 代理符合 MQTT 3.1.1，包括对 QoS 0、QoS 1、QoS 2、保留消息、最后遗嘱消息和永久订阅的本地支持。

  您无需配置此组件即可使用此组件。但是，您可以配置此组件操作 MQTT 代理的端口。默认情况下，使用端口 8883。
+ <a name="client-device-component-overview-mqtt-broker-emqx"></a>[MQTT 5 代理（EMQX）](mqtt-broker-emqx-component.md) (`aws.greengrass.clientdevices.mqtt.EMQX`)
**注意**  
要使用 EMQX MQTT 5 代理，必须使用 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.6.0 或更高版本以及客户端设备身份验证 v2.2.0 或更高版本。

  部署 EMQX MQTT 代理组件，以便在客户端设备和核心设备间的通信中使用 MQTT 5.0 功能。EMQX MQTT 代理符合 MQTT 5.0 的要求，并且支持会话和消息过期间隔、用户属性、共享订阅、主题别名等功能。

  您无需配置此组件即可使用此组件。但是，您可以配置此组件操作 MQTT 代理的端口。默认情况下，使用端口 8883。
+ <a name="client-device-component-overview-mqtt-bridge"></a>[MQTT 网桥](mqtt-bridge-component.md) (`aws.greengrass.clientdevices.mqtt.Bridge`)

  （可选）部署 MQTT 桥接组件，以便在客户端设备（本地 MQTT）、本地发布/订阅和 MQTT 之间中继消息。 AWS IoT Core 将此组件配置为与 Greengrass 组件中的客户端设备同步 AWS IoT Core 并与客户端设备进行交互。

  此组件需要配置才能使用。您必须指定此组件用于中继消息的主题映射。有关更多信息，请参阅 [MQTT 网桥组件配置](mqtt-bridge-component.md#mqtt-bridge-component-configuration)。
+ <a name="client-device-component-overview-ip-detector"></a>[IP 检测器](ip-detector-component.md) (`aws.greengrass.clientdevices.IPDetector`)

  （可选）部署 IP 检测器组件，自动向 AWS IoT Greengrass 云服务报告核心设备的 MQTT 代理端点。如果您的网络设置很复杂（例如路由器将 MQTT 代理端口转发到核心设备），则无法使用此组件。

  您无需配置此组件即可使用此组件。
+ <a name="client-device-component-overview-shadow-manager"></a>[影子管理器](shadow-manager-component.md) (`aws.greengrass.ShadowManager`)
**注意**  
要管理客户端设备影子，必须使用 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.6.0 或更高版本、影子管理器 v2.2.0 或更高版本以及 [MQTT 网桥](mqtt-bridge-component.md) v2.2.0 或更高版本。

  （可选）部署影子管理器组件以管理核心设备上的客户端设备影子。Greengrass 组件可以获取、更新和删除客户端设备影子，以与客户端设备进行交互。您也可以将影子管理器组件配置为将客户端设备影子与 AWS IoT Core 云服务同步。

  要将此组件用于客户端设备影子，必须配置 MQTT 网桥组件，以通过本地发布/订阅在客户端设备和影子管理器间中继消息。否则，此组件无需配置即可使用，但配置后才能同步设备影子。

**注意**  <a name="note-deploy-one-mqtt-broker"></a>
我们建议您仅部署一个 MQTT 代理组件。[MQTT 网桥](mqtt-bridge-component.md)和 [IP 检测器](ip-detector-component.md)组件每次只能使用一个 MQTT 代理组件。如果您部署多个 MQTT 代理组件，您必须将这些组件配置为使用不同的端口。

## 配置云发现（控制台）
<a name="configure-cloud-discovery-console"></a>

您可以使用 AWS IoT Greengrass 控制台关联客户端设备、管理核心设备端点和部署组件以启用客户端设备支持。有关更多信息，请参阅 [第 2 步：启用客户端设备支持](client-devices-tutorial.md#enable-client-device-support)。

## 配置云发现（AWS CLI）
<a name="configure-cloud-discovery-cli"></a>

您可以使用 AWS Command Line Interface (AWS CLI) 关联客户端设备、管理核心设备端点和部署组件以启用客户端设备支持。有关更多信息，请参阅下列内容：
+ [管理客户端设备关联（AWS CLI）](associate-client-devices.md#manage-client-device-associations-cli)
+ [管理核心设备端点](manage-core-device-endpoints.md)
+ [AWS 提供的客户端设备组件](client-device-components.md)
+ [创建部署](create-deployments.md)

# 关联客户端设备
<a name="associate-client-devices"></a>

要使用云发现，请将客户端设备与核心设备关联，以便客户端设备可以发现核心设备。然后，客户端设备可以使用 [Greengrass 发现 API](greengrass-discover-api.md) 来检索其关联核心设备的连接信息和证书。

同样，取消客户端设备与核心设备的关联，可以阻止客户端设备发现核心设备。

**Topics**
+ [管理客户端设备关联（控制台）](#manage-client-device-associations-console)
+ [管理客户端设备关联（AWS CLI）](#manage-client-device-associations-cli)
+ [管理客户端设备关联（API）](#manage-client-device-associations-api)

## 管理客户端设备关联（控制台）
<a name="manage-client-device-associations-console"></a>

您可以使用 AWS IoT Greengrass 控制台查看、添加和删除客户端设备关联。

**查看核心设备的客户端设备关联（控制台）**

1. <a name="navigate-greengrass-console"></a>导航至 [AWS IoT Greengrass 控制台](https://console.aws.amazon.com/greengrass)。

1. 选择**核心设备**。

1. 选择托管管理的核心设备。

1. 在核心设备的详细信息页面上，请选择**客户端设备**选项卡。

1. 在 “**关联的客户端设备**” 部分，您可以看到哪些客户端设备（AWS IoT 事物）与核心设备关联。

**将客户端设备与核心设备关联（控制台）**

1. <a name="navigate-greengrass-console"></a>导航至 [AWS IoT Greengrass 控制台](https://console.aws.amazon.com/greengrass)。

1. 选择**核心设备**。

1. 选择托管管理的核心设备。

1. 在核心设备的详细信息页面上，请选择**客户端设备**选项卡。

1. 在**关联客户端设备**部分，选择**关联客户端设备**。

1. 在**将客户端设备与核心设备关联**模式中，对要关联的每台客户端设备执行以下操作：

   1. 输入要关联为客户端设备 AWS IoT 的事物的名称。

   1. 选择**添加**。

1. 选择**关联 **。

   您关联的客户端设备现在可使用 Greengrass 发现 API 来发现此核心设备。

**取消客户端设备与核心设备的关联（控制台）**

1. <a name="navigate-greengrass-console"></a>导航至 [AWS IoT Greengrass 控制台](https://console.aws.amazon.com/greengrass)。

1. 选择**核心设备**。

1. 选择托管管理的核心设备。

1. 在核心设备的详细信息页面上，请选择**客户端设备**选项卡。

1. 在**已关联的客户端设备**部分中，选择每个要取消关联的客户端设备。

1. 选择**取消关联**。

1. 在确认模式中，选择**取消关联**。

   您取消关联的客户端设备不再使用 Greengrass 发现 API 来发现此核心设备。

## 管理客户端设备关联（AWS CLI）
<a name="manage-client-device-associations-cli"></a>

您可以使用 AWS Command Line Interface (AWS CLI) 来管理核心设备的客户端设备关联。

**查看核心设备的客户端设备关联（AWS CLI）**
+ 使用以下命令：[list-client-devices-associated-with-core-device](https://docs.aws.amazon.com/cli/latest/reference/greengrassv2/list-client-devices-associated-with-core-device.html)。

**将客户端设备与核心设备关联（AWS CLI）**
+ 使用以下命令：[batch-associate-client-device-with-core-device](https://docs.aws.amazon.com/cli/latest/reference/greengrassv2/batch-associate-client-device-with-core-device.html)。

**取消客户端设备与核心设备的关联（AWS CLI）**
+ 使用以下命令：[batch-disassociate-client-device-from-core-device](https://docs.aws.amazon.com/cli/latest/reference/greengrassv2/batch-disassociate-client-device-from-core-device.html)。

## 管理客户端设备关联（API）
<a name="manage-client-device-associations-api"></a>

您可以使用 AWS API 来管理核心设备的客户端设备关联。

**查看核心设备的客户端设备关联 (AWS API)**
+ 使用以下操作：[ListClientDevicesAssociatedWithCoreDevice](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_ListClientDevicesAssociatedWithCoreDevice.html)。

**将客户端设备与核心设备关联 (AWS API)**
+ 使用以下操作：[BatchAssociateClientDeviceWithCoreDevice](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_BatchAssociateClientDeviceWithCoreDevice.html)。

**取消客户端设备与核心设备的关联 (AWS API)**
+ 使用以下操作：[BatchDisassociateClientDeviceFromCoreDevice](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_BatchDisassociateClientDeviceFromCoreDevice.html)。

# 在离线时对客户端进行身份验证
<a name="offline-authentication"></a>

通过*离线身份验证*，您可以配置您的 AWS IoT Greengrass 核心设备，以便即使核心设备未连接到云端，客户端设备也可以连接到核心设备。当您使用离线身份验证时，Greengrass 设备可以在部分离线环境中继续工作。

要对连接到云的客户端设备使用离线身份验证，需要满足以下条件：
+ 部署了[客户端设备身份验证](client-device-auth-component.md)组件的 AWS IoT Greengrass 核心设备。必须使用版本 2.3.0 或更高版本才能进行离线身份验证。
+ 在客户端设备初始连接期间，对核心设备进行云连接。

## 存储客户端凭证
<a name="offline-auth-store-credentials"></a>

当客户端设备首次连接到核心设备时，核心设备会调用该 AWS IoT Greengrass 服务。当被调用时，Greengrass 会将客户端设备的注册作为 AWS IoT 事物进行验证。它还会验证设备是否具有有效证书。然后，核心设备将这些信息存储在本地。

设备下次连接时，Greengrass 核心设备会尝试使用服务验证客户端设备。 AWS IoT Greengrass 如果无法连接 AWS IoT Greengrass，则核心设备将使用其本地存储的设备信息来验证客户端设备。

您可以配置 Greengrass 核心设备存储凭证的时长。通过在[客户端设备身份验证组件配置](https://docs.aws.amazon.com//greengrass/v2/developerguide/client-device-auth-component.html#client-device-auth-component-configuration)中设置 `clientDeviceTrustDurationMinutes` 配置选项，您可以将超时时间从 1 分钟设置为 2,147,483,647 分钟。默认值为 1 分钟，这实际上会关闭离线身份验证。在设置此超时时，建议您考虑安全需求。您还应该考虑核心设备在与云断开连接时预计能运行多长时间。

核心设备会三次更新其凭证存储：

1. 当设备首次连接到核心设备时。

1. 如果核心设备已连接到云，则当客户端设备重新连接到核心设备时。

1. 如果核心设备已连接到云，则每天一次刷新整个凭证存储。

当 Greengrass 核心设备刷新其凭据存储区时，它会使用该操作。[ ListClientDevicesAssociatedWithCoreDevice](https://docs.aws.amazon.com//greengrass/v2/APIReference/API_ListClientDevicesAssociatedWithCoreDevice.html)Greengrass 仅刷新此操作返回的设备。要将客户端设备与核心设备关联，请参阅[关联客户端设备](associate-client-devices.md)。

要使用该`ListClientDevicesAssociatedWithCoreDevice`操作，您必须向与运行的关联的 AWS Identity and Access Management (IAM) 角色添加操作权限 AWS IoT Greengrass。 AWS 账户 有关更多信息，请参阅 [授权核心设备与 AWS 服务交互](device-service-role.md)。

# 管理核心设备端点
<a name="manage-core-device-endpoints"></a>

使用云发现时，会将核心设备的 MQTT 代理端点存储在 AWS IoT Greengrass 云服务中。客户端设备连接到 AWS IoT Greengrass 以检索这些端点及其关联核心设备的其他信息。

对于每台核心设备，都可以自动或手动管理端点。
+ **使用 IP 检测器自动管理端点**

  如果您的网络设置不复杂，例如客户端设备与核心设备位于同一网络中，则可以部署 [IP 检测器组件](ip-detector-component.md)来为您自动管理核心设备端点。例如，如果核心设备位于将 MQTT 代理端口转发到核心设备的路由器后面，则无法使用 IP 检测器组件。

  将 IP 检测器组件部署到事务组也会很有用，因为它可以管理事物组中所有核心设备的端点。有关更多信息，请参阅 [使用 IP 检测器自动管理端点](#use-ip-detector)。
+ **手动管理端点**

  如果无法使用 IP 检测器组件，则必须手动管理核心设备端点。您可以使用控制台或 API 更新这些端点。有关更多信息，请参阅 [手动管理端点](#manually-manage-endpoints)。

**Topics**
+ [使用 IP 检测器自动管理端点](#use-ip-detector)
+ [手动管理端点](#manually-manage-endpoints)

## 使用 IP 检测器自动管理端点
<a name="use-ip-detector"></a>

如果您的网络设置很简单，例如客户端设备与核心设备位于同一网络中，则可以部署 [IP 检测器组件](ip-detector-component.md)来执行以下操作：
+ 监控 Greengrass 核心设备的本地网络连接信息。此信息包括核心设备的网络端点和 MQTT 代理运行的端口。
+ 向 AWS IoT Greengrass 云服务报告核心设备的连接信息。

IP 检测器组件会覆盖您手动设置的端点。

**重要**  
核心设备的 AWS IoT 策略必须允许使用 IP 检测器组件的`greengrass:UpdateConnectivityInfo`权限。有关更多信息，请参阅[AWS IoT 数据平面操作策略](device-auth.md#iot-policies)和[配置 AWS IoT 事物策略](connect-client-devices.md#configure-iot-policy-requirement)。

您可以执行以下任一操作来部署 IP 检测器组件：
+ 使用控制台中的**配置发现**页面。有关更多信息，请参阅 [配置云发现（控制台）](connect-client-devices.md#configure-cloud-discovery-console)。
+ 创建和修改部署以包含 IP 检测器。您可以使用控制台或 AWS API 来管理部署。 AWS CLI有关更多信息，请参阅 [创建部署](create-deployments.md)。

### 部署 IP 检测器组件（控制台）
<a name="deploy-ip-detector-console"></a>

1. 在 [AWS IoT Greengrass 控制台](https://console.aws.amazon.com/greengrass)导航菜单中，选择**组件**。

1. 在**组件**页面上，选择**公有组件**选项卡，然后选择 **aws.greengrass.clientdevices.IPDetector**。

1. 在 **aws.greengrass.clientdevices.IPDetector** 页面上，选择**部署**。

1. <a name="deploy-component-choose-deployment-step"></a>从**添加到部署**中，选择要修改的现有部署，或者选择创建新部署，然后选择**下一步**。

1. <a name="deploy-component-choose-target-step"></a>如果您选择创建新部署，请为部署选择目标核心设备或事物组。在**指定目标**页面的**部署目标**下面，选择核心设备或事物组，然后选择**下一步**。

1. 在**选择组件**页面上，确认已选择 **aws.greengrass.clientdevices.IPDetector** 组件，然后选择**下一步**。

1. 在**配置组件**页面上，选择 **aws.greengrass.clientdevices.IPDetector**，然后执行以下操作：

   1. 选择**配置组件**。

   1. 在**配置 aws.greengrass.clientdevices.IPDetector** 模式的**配置更新**下，在**要合并的配置**中输入配置更新来配置 IP 检测器组件。您可以指定以下任意配置选项：
      + `defaultPort` –<a name="ip-detector-component-configuration-default-port-definition"></a>（可选）此组件检测到 IP 地址时要报告的 MQTT 代理端口。如果您将 MQTT 代理配置为使用默认端口 8883 以外的端口，则必须指定此参数。
      + `includeIPv4LoopbackAddrs`—<a name="ip-detector-component-configuration-include-ipv4-loopback-addrs-definition"></a>（可选）您可以启用此选项来检测和报告 IPv4 环回地址。这些是 IP 地址（例如 `localhost`），设备可以在此与自身通信。在核心设备和客户端设备运行于同一系统的测试环境中使用此选项。
      + `includeIPv4LinkLocalAddrs`—<a name="ip-detector-component-configuration-include-ipv4-link-local-addrs-definition"></a>（可选）您可以启用此选项来检测和报告 IPv4 [链路本地地址](https://en.wikipedia.org/wiki/Link-local_address)。如果核心设备的网络没有动态主机配置协议（DHCP）或静态分配的 IP 地址，请使用此选项。
      + `includeIPv6LoopbackAddrs`—<a name="ip-detector-component-configuration-include-ipv6-loopback-addrs-definition"></a>（可选）您可以启用此选项来检测和报告 IPv6 环回地址。这些是 IP 地址（例如 `localhost`），设备可以在此与自身通信。在核心设备和客户端设备运行于同一系统的测试环境中使用此选项。您必须将 `includeIPv4Addrs` 设置为 `false` 并将 `includeIPv6Addrs` 设置为 `true` 才能使用此选项。您必须具有 IP 检测器 v2.2.0 或更高版本才能使用此选项。
      + `includeIPv6LinkLocalAddrs`—<a name="ip-detector-component-configuration-include-ipv6-link-local-addrs-definition"></a>（可选）您可以启用此选项来检测和报告 IPv6 [链路本地地址](https://en.wikipedia.org/wiki/Link-local_address)。如果核心设备的网络没有动态主机配置协议（DHCP）或静态分配的 IP 地址，请使用此选项。您必须将 `includeIPv4Addrs` 设置为 `false` 并将 `includeIPv6Addrs` 设置为 `true` 才能使用此选项。您必须具有 IP 检测器 v2.2.0 或更高版本才能使用此选项。
      + `includeIPv4Addrs` –<a name="ip-detector-component-configuration-include-ipv4-addrs-definition"></a>（可选）默认值设置为 true。您可以启用此选项来发布在核心设备上找到 IPv4 的地址。您必须具有 IP 检测器 v2.2.0 或更高版本才能使用此选项。
      + `includeIPv6Addrs`—<a name="ip-detector-component-configuration-include-ipv6-addrs-definition"></a>（可选）您可以启用此选项以发布在核心设备上找到 IPv6 的地址。将 `includeIPv4Addrs` 设置为 `false` 以使用此选项。您必须具有 IP 检测器 v2.2.0 或更高版本才能使用此选项。

      配置更新可能与以下示例类似。

      ```
      {
        "defaultPort": "8883",
        "includeIPv4LoopbackAddrs": false,
        "includeIPv4LinkLocalAddrs": false
      }
      ```

   1. 选择**确认**以关闭模式，然后选择**下一步**。

1. <a name="deploy-component-configure-advanced-settings-step"></a>在**配置高级设置**页面上，保留默认配置设置，然后选择**下一步**。

1. <a name="deploy-component-review-and-deploy-step"></a>在 **检查** 页上，选择 **部署**。

   完成部署可能最多需要 1 分钟。

### 部署 IP 检测器组件（AWS CLI）
<a name="deploy-ip-detector-cli"></a>

要部署 IP 检测器组件，请创建 `components` 对象中包含 `aws.greengrass.clientdevices.IPDetector` 的部署文档，并指定该组件的配置更新。按照 [创建部署](create-deployments.md) 中的说明创建新部署或修改现有部署。

在创建部署文档时，您可以指定以下任意选项来配置 IP 检测器组件：
+ `defaultPort` –<a name="ip-detector-component-configuration-default-port-definition"></a>（可选）此组件检测到 IP 地址时要报告的 MQTT 代理端口。如果您将 MQTT 代理配置为使用默认端口 8883 以外的端口，则必须指定此参数。
+ `includeIPv4LoopbackAddrs`—<a name="ip-detector-component-configuration-include-ipv4-loopback-addrs-definition"></a>（可选）您可以启用此选项来检测和报告 IPv4 环回地址。这些是 IP 地址（例如 `localhost`），设备可以在此与自身通信。在核心设备和客户端设备运行于同一系统的测试环境中使用此选项。
+ `includeIPv4LinkLocalAddrs`—<a name="ip-detector-component-configuration-include-ipv4-link-local-addrs-definition"></a>（可选）您可以启用此选项来检测和报告 IPv4 [链路本地地址](https://en.wikipedia.org/wiki/Link-local_address)。如果核心设备的网络没有动态主机配置协议（DHCP）或静态分配的 IP 地址，请使用此选项。
+ `includeIPv6LoopbackAddrs`—<a name="ip-detector-component-configuration-include-ipv6-loopback-addrs-definition"></a>（可选）您可以启用此选项来检测和报告 IPv6 环回地址。这些是 IP 地址（例如 `localhost`），设备可以在此与自身通信。在核心设备和客户端设备运行于同一系统的测试环境中使用此选项。您必须将 `includeIPv4Addrs` 设置为 `false` 并将 `includeIPv6Addrs` 设置为 `true` 才能使用此选项。您必须具有 IP 检测器 v2.2.0 或更高版本才能使用此选项。
+ `includeIPv6LinkLocalAddrs`—<a name="ip-detector-component-configuration-include-ipv6-link-local-addrs-definition"></a>（可选）您可以启用此选项来检测和报告 IPv6 [链路本地地址](https://en.wikipedia.org/wiki/Link-local_address)。如果核心设备的网络没有动态主机配置协议（DHCP）或静态分配的 IP 地址，请使用此选项。您必须将 `includeIPv4Addrs` 设置为 `false` 并将 `includeIPv6Addrs` 设置为 `true` 才能使用此选项。您必须具有 IP 检测器 v2.2.0 或更高版本才能使用此选项。
+ `includeIPv4Addrs` –<a name="ip-detector-component-configuration-include-ipv4-addrs-definition"></a>（可选）默认值设置为 true。您可以启用此选项来发布在核心设备上找到 IPv4 的地址。您必须具有 IP 检测器 v2.2.0 或更高版本才能使用此选项。
+ `includeIPv6Addrs`—<a name="ip-detector-component-configuration-include-ipv6-addrs-definition"></a>（可选）您可以启用此选项以发布在核心设备上找到 IPv6 的地址。将 `includeIPv4Addrs` 设置为 `false` 以使用此选项。您必须具有 IP 检测器 v2.2.0 或更高版本才能使用此选项。

以下示例部分部署文档指定将端口 8883 报告为 MQTT 代理端口。

```
{
  ...,
  "components": {
    ...,
    "aws.greengrass.clientdevices.IPDetector": {
      "componentVersion": "2.1.1",
      "configurationUpdate": {
        "merge": "{\"defaultPort\":\"8883\",}"
      }
    }
  }
}
```

## 手动管理端点
<a name="manually-manage-endpoints"></a>

您可以手动管理核心设备 MQTT 代理端点。

每个 MQTT 代理端点都具有以下信息：

**端点** (`HostAddress`)  
客户端设备可以连接到核心设备上 MQTT 代理的 IP 地址或 DNS 地址。

**端口** (`PortNumber`)  
MQTT 代理在核心设备上运行的端口。  
您可以在 [Moquette MQTT 代理组件](mqtt-broker-moquette-component.md)上配置此端口，默认使用端口 8883。

**元数据** (`Metadata`)  
要提供给连接到此端点的客户端设备的其他元数据。

**Topics**
+ [管理端点（控制台）](#manually-manage-endpoints-console)
+ [管理端点（AWS CLI）](#manually-manage-endpoints-cli)
+ [管理端点（API）](#manually-manage-endpoints-api)

### 管理端点（控制台）
<a name="manually-manage-endpoints-console"></a>

您可以使用 AWS IoT Greengrass 控制台查看、更新和移除核心设备的端点。

**管理核心设备端点（控制台）**

1. <a name="navigate-greengrass-console"></a>导航至 [AWS IoT Greengrass 控制台](https://console.aws.amazon.com/greengrass)。

1. 选择**核心设备**。

1. 选择托管管理的核心设备。

1. 在核心设备的详细信息页面上，请选择**客户端设备**选项卡。

1. 在 **MQTT 代理端点**部分，您可以看到核心设备的 MQTT 代理端点。选择**管理端点**。

1. 在**管理端点**模式中，添加或删除核心设备的 MQTT 代理端点。

1. 选择**更新**。

### 管理端点（AWS CLI）
<a name="manually-manage-endpoints-cli"></a>

您可以使用 AWS Command Line Interface (AWS CLI) 来管理核心设备的端点。

**注意**  
由于中的 AWS IoT Greengrass V2 客户端设备支持向后兼容 AWS IoT Greengrass V1，因此您可以使用 AWS IoT Greengrass V2 或 AWS IoT Greengrass V1 API 操作来管理核心设备端点。

**获取核心设备端点（AWS CLI）**
+ 使用以下命令之一：
  + [greengrassv2： get-connectivity-info](https://docs.aws.amazon.com/cli/latest/reference/greengrassv2/get-connectivity-info.html)
  + [greengrass: get-connectivity-info](https://docs.aws.amazon.com/cli/latest/reference/greengrass/get-connectivity-info.html)

**更新核心设备端点（AWS CLI）**
+ 使用以下命令之一：
  + [greengrassv2： update-connectivity-info](https://docs.aws.amazon.com/cli/latest/reference/greengrassv2/update-connectivity-info.html)
  + [greengrass: update-connectivity-info](https://docs.aws.amazon.com/cli/latest/reference/greengrass/update-connectivity-info.html)

### 管理端点（API）
<a name="manually-manage-endpoints-api"></a>

您可以使用 AWS API 来管理核心设备的终端节点。

**注意**  
由于中的 AWS IoT Greengrass V2 客户端设备支持向后兼容 AWS IoT Greengrass V1，因此您可以使用 AWS IoT Greengrass V2 或 AWS IoT Greengrass V1 API 操作来管理核心设备端点。

**获取核心设备的终端节点 (AWS API)**
+ 请使用以下任一操作：
  + [V2: GetConnectivityInfo](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_GetConnectivityInfo.html)
  + [V1: GetConnectivityInfo](https://docs.aws.amazon.com/greengrass/v1/apireference/getconnectivityinfo-get.html)

**更新核心设备的终端节点 (AWS API)**
+ 请使用以下任一操作：
  + [V2: UpdateConnectivityInfo](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_UpdateConnectivityInfo.html)
  + [V1: UpdateConnectivityInfo](https://docs.aws.amazon.com/greengrass/v1/apireference/updateconnectivityinfo-put.html)

# 选择 MQTT 代理
<a name="choose-local-mqtt-broker"></a>

AWS IoT Greengrass 提供选项，供您选择要在核心设备上运行的本地 MQTT 代理。客户端设备连接到在核心设备上运行的 MQTT 代理，因此请选择与您要连接的客户端设备兼容的 MQTT 代理。

**注意**  <a name="note-deploy-one-mqtt-broker"></a>
我们建议您仅部署一个 MQTT 代理组件。[MQTT 网桥](mqtt-bridge-component.md)和 [IP 检测器](ip-detector-component.md)组件每次只能使用一个 MQTT 代理组件。如果您部署多个 MQTT 代理组件，您必须将这些组件配置为使用不同的端口。

您可从以下 MQTT 代理中进行选择：
+ **[MQTT 3.1.1 代理（Moquette）](mqtt-broker-moquette-component.md)**– `aws.greengrass.clientdevices.mqtt.Moquette`

  对于符合 MQTT 3.1.1 标准的轻量级 MQTT 代理，请选择此选项。AWS IoT Core MQTT 代理和 AWS IoT Device SDK 也符合 MQTT 3.1.1 标准，因此您可以使用这些功能来创建可跨您的设备和 AWS 云 使用 MQTT 3.1.1 的应用程序。
+ **[MQTT 5 代理（EMQX）](mqtt-broker-emqx-component.md)**– `aws.greengrass.clientdevices.mqtt.EMQX`

  选择此选项可在核心设备与客户端设备通信时使用 MQTT 5 功能。该组件使用的资源比 Moquette MQTT 3.1.1 代理要多，并且在 Linux 核心设备上，它需要 Docker。

  MQTT 5 与 MQTT 3.1.1 向后兼容，因此您可以将使用 MQTT 3.1.1 的客户端设备连接到该代理。如果您运行 Moquette MQTT 3.1.1 代理，您可以将其替换为 EMQX MQTT 5 代理，并且客户端设备可以继续照常连接和运行。

  <a name="note-local-mqtt-broker-mqtt-5-features"></a>
+ **实施自定义代理**

  选择此选项可创建自定义本地代理组件以与客户端设备通信。您可以创建使用 MQTT 之外的协议的自定义本地代理。AWS IoT Greengrass 提供组件 SDK，用于对客户端设备进行身份验证和授权。有关更多信息，请参阅[使用 AWS IoT Device SDK 与 Greengrass 原子核、其他组件进行通信，以及 AWS IoT Core与 Greengrass 核、其他组件进行通信 AWS IoT Core](interprocess-communication.md)和[对客户端设备进行身份验证和授权](ipc-client-device-auth.md)。

# 使用 MQTT 代理将客户端设备连接到 AWS IoT Greengrass 核心设备
<a name="connecting-to-mqtt"></a>

当您在 AWS IoT Greengrass 核心设备上使用 MQTT 代理时，设备会使用设备独有的*核心设备证书颁发机构 (CA)* 向代理颁发证书，以便与客户端建立双向 TLS 连接。

AWS IoT Greengrass 将自动生成核心设备 CA，或者您可以提供自己的 CA。连接[客户端设备身份验证](client-device-auth-component.md)组件 AWS IoT Greengrass 时，核心设备 CA 即注册到其中。自动生成的核心设备 CA 是永久性的，只要配置了客户端设备身份验证组件，该设备就会持续使用同一 CA。

启动 MQTT 代理后，它会请求证书。客户端设备身份验证组件使用核心设备 CA 颁发 X.509 证书。代理启动、证书过期或连接信息（例如 IP 地址）发生变化时，将轮换证书。有关更多信息，请参阅[本地 MQTT 代理的证书轮换](device-auth.md#mqtt-certificate-expiration)。

要将客户端连接到 MQTT 代理，您需要满足以下条件：
+ 客户端设备必须具有 AWS IoT Greengrass 核心设备 CA。您可以通过云发现或手动提供 CA 来获取此 CA。有关更多信息，请参阅[使用您自己的证书颁发机构](#use-your-own-CA)。
+ 核心设备 CA 颁发的代理证书中必须提供核心设备的完全限定域名（FQDN）或 IP 地址。您可以使用 [IP 检测器](ip-detector-component.md) 组件或通过手动配置 IP 地址来确保这一点。有关更多信息，请参阅[管理核心设备端点](manage-core-device-endpoints.md)。
+ 客户端设备身份验证组件必须授予客户端设备连接到 Greengrass 核心设备的权限。有关更多信息，请参阅[客户端设备身份验证](client-device-auth-component.md)。

## 使用您自己的证书颁发机构
<a name="use-your-own-CA"></a>

如果您的客户端设备无法通过访问云来发现您的核心设备，则您可以提供*核心设备证书颁发机构（CA）*。您的 Greengrass 核心设备使用核心设备 CA 来为您的 MQTT 代理颁发证书。配置核心设备并使用其 CA 预置客户端设备后，您的客户端设备就可以连接到端点并使用核心设备 CA（您自己提供的 CA 或自动生成的 CA）来验证 TLS 握手。

要将 [客户端设备身份验证](client-device-auth-component.md) 组件配置为使用您的核心设备 CA，请在部署组件时设置 `certificateAuthority` 配置参数。您必须在配置过程中提供以下详细信息：
+ 核心设备 CA 证书的位置。
+ 核心设备 CA 证书的私有密钥。
+ （可选）如果核心设备 CA 是中间 CA，则为指向根证书的证书链。

如果您提供核心设备 CA，请将该 CA AWS IoT Greengrass 注册到云端。

您可以将证书存储在硬件安全模块或文件系统中。以下示例显示了使用 HSM/TPM 存储的中间 CA 的 `certificateAuthority` 配置。请注意，证书链只能存储在磁盘上。

```
  "certificateAuthority": {
      "certificateUri": "pkcs11:object=CustomerIntermediateCA;type=cert",
      "privateKeyUri": "pkcs11:object=CustomerIntermediateCA;type=private"
      "certificateChainUri": "file:///home/ec2-user/creds/certificateChain.pem",
    }
```

在此示例中，`certificateAuthority` 配置参数会将客户端设备身份验证组件配置为使用文件系统中的中间 CA：

```
  "certificateAuthority": {
      "certificateUri": "file:///home/ec2-user/creds/intermediateCA.pem",
      "privateKeyUri": "file:///home/ec2-user/creds/intermediateCA.privateKey.pem",
      "certificateChainUri": "file:///home/ec2-user/creds/certificateChain.pem",
    }
```

要将设备连接到您的 AWS IoT Greengrass Core 设备，请执行以下操作：

1. 使用您所在组织的根 CA 为 Greengrass 核心设备创建中间证书颁发机构（CA）。我们建议您使用中间 CA 作为最佳安全实践。

1. 向 Greengrass 核心设备提供中间 CA 证书、私有密钥，以及指向您根 CA 的证书链。有关更多信息，请参阅 [客户端设备身份验证](client-device-auth-component.md)。中间 CA 成为 Greengrass 核心设备的核心设备 CA，设备向注册 CA。 AWS IoT Greengrass

1. 将客户端设备注册为 AWS IoT 事物。有关更多信息，请参阅《AWS IoT Core 开发人员指南》**中的[创建事物对象](https://docs.aws.amazon.com/iot/latest/developerguide/create-iot-resources.html#create-aws-thing)。将私有密钥、公有密钥、设备证书和根 CA 证书添加到客户端设备。如何添加信息取决于您的设备和软件。

配置设备后，您就可以使用证书和公有密钥链连接到 Greengrass 核心设备。您的软件负责查找核心设备端点。您可以手动为核心设备设置端点。有关更多信息，请参阅 [手动管理端点](manage-core-device-endpoints.md#manually-manage-endpoints)。

# 测试客户端设备通信
<a name="test-client-device-communications"></a>

客户端设备可以使用 AWS IoT Device SDK 来发现、连接核心设备并与之通信。您可以使用中的 Greengrass 发现客户端 AWS IoT Device SDK 来使用 Greengras [s 发现 API，它会返回有关客户端设备](greengrass-discover-api.md)可以连接的核心设备的信息。API 响应包括要连接的 MQTT 代理端点和用于验证每台核心设备身份的证书。然后，客户端设备可以尝试连接每个端点，直至其成功连接核心设备。

客户端设备仅能发现您与之关联的核心设备。在测试客户端设备与核心设备之间的通信之前，必须将客户端设备与核心设备相关联。有关更多信息，请参阅 [关联客户端设备](associate-client-devices.md)。

Greengrass Discovery API 会返回您指定的核心设备 MQTT 代理端点。您可以使用 [IP 检测器组件](ip-detector-component.md)为您管理这些端点，也可以手动管理每台核心设备的端点。有关更多信息，请参阅 [管理核心设备端点](manage-core-device-endpoints.md)。

**注意**  
要使用 Greengrass Discovery API，客户端设备必须拥有 `greengrass:Discover` 权限。有关更多信息，请参阅 [客户端设备的最低 AWS IoT 政策](device-auth.md#client-device-minimal-iot-policy)。

 AWS IoT Device SDK 有多种编程语言版本。有关更多信息，请参阅《*AWS IoT Core 开发者指南*》 SDKs中的[AWS IoT 设备](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html)。

**Topics**
+ [测试通信（Python）](#test-client-device-communications-python)
+ [测试通信（C\$1\$1）](#test-client-device-communications-cpp)
+ [测试通信 (JavaScript)](#test-client-device-communications-javascript)
+ [测试通信（Java）](#test-client-device-communications-java)

## 测试通信（Python）
<a name="test-client-device-communications-python"></a>

在本节中，您将使用[适用于 Python 的AWS IoT Device SDK v2](https://github.com/aws/aws-iot-device-sdk-python-v2) 中的 Greengrass Discovery 示例来测试客户端设备与核心设备之间的通信。

**重要**  
要使用适用于 Python 的 AWS IoT Device SDK v2，设备必须运行 Python 3.6 或更高版本。

**测试通信（适用于 Python 的AWS IoT Device SDK v2）**

1. <a name="download-iot-device-sdk-python-v2"></a>下载[适用于 Python 的AWS IoT Device SDK v2](https://github.com/aws/aws-iot-device-sdk-python-v2) 并将其安装到要作为客户端设备连接的设备上。 AWS IoT 

   在客户端设备上，执行以下操作：

   1. 克隆适用于 Python 的 AWS IoT Device SDK v2 版本库进行下载。

      ```
      git clone https://github.com/aws/aws-iot-device-sdk-python-v2.git
      ```

   1. 安装适用于 Python 的 AWS IoT Device SDK v2。

      ```
      python3 -m pip install --user ./aws-iot-device-sdk-python-v2
      ```

1. <a name="cd-iot-device-sdk-python-v2"></a>在 python 版 AWS IoT Device SDK v2 中切换到示例文件夹。

   ```
   cd aws-iot-device-sdk-python-v2/samples/greengrass
   ```

1. <a name="test-client-device-communications-application-intro"></a>运行示例 Greengrass Discovery 应用程序。此应用程序需要指定客户端设备事物名称、要使用的 MQTT 主题和消息以及用于验证和保护连接的证书的参数。以下示例向 `clients/MyClientDevice1/hello/world` 主题发送“Hello World”消息。<a name="test-client-device-communications-application-command-replace"></a>
   + *MyClientDevice1*替换为客户端设备的事物名称。
   + *\$1/certs/AmazonRootCA1.pem*替换为客户端设备上的 Amazon 根 CA 证书的路径。
   + *\$1/certs/device.pem.crt*替换为客户端设备上设备证书的路径。
   + *\$1/certs/private.pem.key*替换为客户端设备上私钥文件的路径。
   + *us-east-1*替换为您的客户端设备和核心设备运行的地 AWS 区。

   ```
   python3 basic_discovery.py \\
     --thing_name MyClientDevice1 \\
     --topic 'clients/MyClientDevice1/hello/world' \\
     --message 'Hello World!' \\
     --ca_file ~/certs/AmazonRootCA1.pem \\
     --cert ~/certs/device.pem.crt \\
     --key ~/certs/private.pem.key \\
     --region us-east-1 \\
     --verbosity Warn
   ```

   <a name="test-client-device-communications-application-output-intro"></a>发现示例应用程序发送消息 10 次并断开连接。它还订阅在其中发布消息的同一主题。如果输出显示应用程序收到了有关该主题的 MQTT 消息，则客户端设备可以成功地与核心设备通信。

   ```
   Performing greengrass discovery...
   awsiot.greengrass_discovery.DiscoverResponse(gg_groups=[awsiot.greengrass_discovery.GGGroup(gg_group_id='greengrassV2-coreDevice-MyGreengrassCore', cores=[awsiot.greengrass_discovery.GGCore(thing_arn='arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore', connectivity=[awsiot.greengrass_discovery.ConnectivityInfo(id='203.0.113.0', host_address='203.0.113.0', metadata='', port=8883)])], certificate_authorities=['-----BEGIN CERTIFICATE-----\
   MIICiT...EXAMPLE=\
   -----END CERTIFICATE-----\
   '])])
   Trying core arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore at host 203.0.113.0 port 8883
   Connected!
   Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 0}
   
   Publish received on topic clients/MyClientDevice1/hello/world
   b'{"message": "Hello World!", "sequence": 0}'
   Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 1}
   
   Publish received on topic clients/MyClientDevice1/hello/world
   b'{"message": "Hello World!", "sequence": 1}'
   
   ...
   
   Published topic clients/MyClientDevice1/hello/world: {"message": "Hello World!", "sequence": 9}
   
   Publish received on topic clients/MyClientDevice1/hello/world
   b'{"message": "Hello World!", "sequence": 9}'
   ```

   <a name="test-client-device-communications-application-troubleshooting"></a>如果应用程序输出的是错误，请参阅 [Greengrass 发现问题疑难解答](troubleshooting-client-devices.md#greengrass-discovery-issues)。

   <a name="test-client-device-communications-application-view-core-logs"></a>您还可以查看核心设备上的 Greengrass 日志，以验证客户端设备是否成功连接和发送消息。有关更多信息，请参阅 [监控 AWS IoT Greengrass 日志](monitor-logs.md)。

## 测试通信（C\$1\$1）
<a name="test-client-device-communications-cpp"></a>

在本节中，您将使用[适用于 C\$1\$1 的AWS IoT Device SDK v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2) 中的 Greengrass Discovery 示例来测试客户端设备与核心设备之间的通信。

<a name="iot-device-sdk-cpp-v2-build-requirements-intro"></a>要构建 C\$1\$1 版 AWS IoT Device SDK v2，设备必须具有以下工具：<a name="iot-device-sdk-cpp-v2-build-requirements"></a>
+ C\$1\$1 11 或更高版本
+ CMake 3.1 或更高版本
+ 以下编译器之一：
  + GCC 4.8 或更高版本
  + Clang 3.9 或更高版本
  + MSVC 2015 或更高版本

**测试通信（适用于 C\$1\$1 的AWS IoT Device SDK v2）**

1. 下载并构建 [C\$1\$1 版AWS IoT Device SDK v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2) 以 AWS IoT 将其作为客户端设备进行连接。

   在客户端设备上，执行以下操作：

   1. 为 AWS IoT Device SDK v2 for C\$1\$1 工作区创建一个文件夹，然后更改为该文件夹。

      ```
      cd
      mkdir iot-device-sdk-cpp
      cd iot-device-sdk-cpp
      ```

   1. 克隆适用于 C\$1\$1 的 AWS IoT Device SDK v2 存储库进行下载。`--recursive` 标记指定下载子模块。

      ```
      git clone --recursive https://github.com/aws/aws-iot-device-sdk-cpp-v2.git
      ```

   1. 为 AWS IoT Device SDK v2 for C\$1\$1 编译输出创建一个文件夹，然后更改为该文件夹。

      ```
      mkdir aws-iot-device-sdk-cpp-v2-build
      cd aws-iot-device-sdk-cpp-v2-build
      ```

   1. 为 C\$1\$1 构建 AWS IoT Device SDK v2。

      ```
      cmake -DCMAKE_INSTALL_PREFIX="~/iot-device-sdk-cpp" -DCMAKE_BUILD_TYPE="Release" ../aws-iot-device-sdk-cpp-v2
      cmake --build . --target install
      ```

1. 在 v2 中构建 C\$1\$1 版 Greengrass 发现示例应用程序。 AWS IoT Device SDK 执行以下操作：

   1. 切换到 C\$1\$1 版 v2 中的 Greengrass 发现示例文件夹。 AWS IoT Device SDK 

      ```
      cd ../aws-iot-device-sdk-cpp-v2/samples/greengrass/basic_discovery
      ```

   1. 为 Greengrass Discovery 示例构建输出创建一个文件夹，然后更改为该文件夹。

      ```
      mkdir build
      cd build
      ```

   1. 构建 Greengrass Discovery 示例应用程序。

      ```
      cmake -DCMAKE_PREFIX_PATH="~/iot-device-sdk-cpp" -DCMAKE_BUILD_TYPE="Release" ..
      cmake --build . --config "Release"
      ```

1. <a name="test-client-device-communications-application-scanner-intro"></a>运行示例 Greengrass Discovery 应用程序。此应用程序需要指定客户端设备事物名称、要使用的 MQTT 主题以及用于验证和保护连接的证书的参数。以下示例订阅了 `clients/MyClientDevice1/hello/world` 主题，并将您在命令行中输入的消息发布至同一主题。<a name="test-client-device-communications-application-command-replace"></a>
   + *MyClientDevice1*替换为客户端设备的事物名称。
   + *\$1/certs/AmazonRootCA1.pem*替换为客户端设备上的 Amazon 根 CA 证书的路径。
   + *\$1/certs/device.pem.crt*替换为客户端设备上设备证书的路径。
   + *\$1/certs/private.pem.key*替换为客户端设备上私钥文件的路径。
   + *us-east-1*替换为您的客户端设备和核心设备运行的地 AWS 区。

   ```
   ./basic-discovery \
     --thing_name MyClientDevice1 \
     --topic 'clients/MyClientDevice1/hello/world' \
     --ca_file ~/certs/AmazonRootCA1.pem \
     --cert ~/certs/device.pem.crt \
     --key ~/certs/private.pem.key \
     --region us-east-1
   ```

   <a name="test-client-device-communications-application-scanner-output-intro"></a>Discovery 示例应用程序订阅主题并提示您输入要发布的消息。

   ```
   Connecting to group greengrassV2-coreDevice-MyGreengrassCore with thing arn arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore, using endpoint 203.0.113.0:8883
   Connected to group greengrassV2-coreDevice-MyGreengrassCore, using connection to 203.0.113.0:8883
   Successfully subscribed to clients/MyClientDevice1/hello/world
   Enter the message you want to publish to topic clients/MyClientDevice1/hello/world and press enter. Enter 'exit' to exit this program.
   ```

   <a name="test-client-device-communications-application-troubleshooting"></a>如果应用程序输出的是错误，请参阅 [Greengrass 发现问题疑难解答](troubleshooting-client-devices.md#greengrass-discovery-issues)。

1. <a name="test-client-device-communications-application-scanner-input"></a>输入一条消息，例如 **Hello World\$1**。

   ```
   Enter the message you want to publish to topic clients/MyClientDevice1/hello/world and press enter. Enter 'exit' to exit this program.
   Hello World!
   ```

   <a name="test-client-device-communications-application-scanner-input-output"></a>如果输出显示应用程序收到了有关该主题的 MQTT 消息，则客户端设备可以成功地与核心设备通信。

   ```
   Operation on packetId 2 Succeeded
   Publish received on topic clients/MyClientDevice1/hello/world
   Message:
   Hello World!
   ```

   <a name="test-client-device-communications-application-view-core-logs"></a>您还可以查看核心设备上的 Greengrass 日志，以验证客户端设备是否成功连接和发送消息。有关更多信息，请参阅 [监控 AWS IoT Greengrass 日志](monitor-logs.md)。

## 测试通信 (JavaScript)
<a name="test-client-device-communications-javascript"></a>

在本节中，您将使用 [v2 JavaScript](https://github.com/aws/aws-iot-device-sdk-js-v2) 中的AWS IoT Device SDK Greengrass 发现示例来测试客户端设备与核心设备之间的通信。

**重要**  
要将 AWS IoT Device SDK v2 用于 JavaScript，设备必须运行 Node v10.0 或更高版本。

**测试通信（AWS IoT Device SDK v2 适用于 JavaScript）**

1. 下载并安装该设备[的AWS IoT Device SDK JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2) 以作为客户端设备进行连接。 AWS IoT 

   在客户端设备上，执行以下操作：

   1. 克隆 AWS IoT Device SDK v2 以供 JavaScript 存储库下载。

      ```
      git clone https://github.com/aws/aws-iot-device-sdk-js-v2.git
      ```

   1. 安装适用的 AWS IoT Device SDK v2。 JavaScript

      ```
      cd aws-iot-device-sdk-js-v2
      npm install
      ```

1. 切换到 v2 中的 Greengrass 发现示例文件夹。 AWS IoT Device SDK JavaScript

   ```
   cd samples/node/greengrass/basic_discovery
   ```

1. 安装 Greengrass Discovery 示例应用程序。

   ```
   npm install
   ```

1. <a name="test-client-device-communications-application-intro"></a>运行示例 Greengrass Discovery 应用程序。此应用程序需要指定客户端设备事物名称、要使用的 MQTT 主题和消息以及用于验证和保护连接的证书的参数。以下示例向 `clients/MyClientDevice1/hello/world` 主题发送“Hello World”消息。<a name="test-client-device-communications-application-command-replace"></a>
   + *MyClientDevice1*替换为客户端设备的事物名称。
   + *\$1/certs/AmazonRootCA1.pem*替换为客户端设备上的 Amazon 根 CA 证书的路径。
   + *\$1/certs/device.pem.crt*替换为客户端设备上设备证书的路径。
   + *\$1/certs/private.pem.key*替换为客户端设备上私钥文件的路径。
   + *us-east-1*替换为您的客户端设备和核心设备运行的地 AWS 区。

   ```
   node dist/index.js \
     --thing_name MyClientDevice1 \
     --topic 'clients/MyClientDevice1/hello/world' \
     --message 'Hello World!' \
     --ca_file ~/certs/AmazonRootCA1.pem \
     --cert ~/certs/device.pem.crt \
     --key ~/certs/private.pem.key \
     --region us-east-1 \
     --verbose warn
   ```

   <a name="test-client-device-communications-application-output-intro"></a>发现示例应用程序发送消息 10 次并断开连接。它还订阅在其中发布消息的同一主题。如果输出显示应用程序收到了有关该主题的 MQTT 消息，则客户端设备可以成功地与核心设备通信。

   ```
   Discovery Response:
   {"gg_groups":[{"gg_group_id":"greengrassV2-coreDevice-MyGreengrassCore","cores":[{"thing_arn":"arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore","connectivity":[{"id":"203.0.113.0","host_address":"203.0.113.0","port":8883,"metadata":""}]}],"certificate_authorities":["-----BEGIN CERTIFICATE-----\nMIICiT...EXAMPLE=\n-----END CERTIFICATE-----\n"]}]}
   Trying endpoint={"id":"203.0.113.0","host_address":"203.0.113.0","port":8883,"metadata":""}
   [WARN] [2021-06-12T00:46:45Z] [00007f90c0e8d700] [socket] - id=0x7f90b8018710 fd=26: setsockopt() for NO_SIGNAL failed with errno 92. If you are having SIGPIPE signals thrown, you may want to install a signal trap in your application layer.
   Connected to endpoint={"id":"203.0.113.0","host_address":"203.0.113.0","port":8883,"metadata":""}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":1}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":2}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":3}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":4}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":5}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":6}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":7}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":8}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":9}
   Publish received. topic:"clients/MyClientDevice1/hello/world" dup:false qos:0 retain:false
   {"message":"Hello World!","sequence":10}
   Complete!
   ```

   <a name="test-client-device-communications-application-troubleshooting"></a>如果应用程序输出的是错误，请参阅 [Greengrass 发现问题疑难解答](troubleshooting-client-devices.md#greengrass-discovery-issues)。

   <a name="test-client-device-communications-application-view-core-logs"></a>您还可以查看核心设备上的 Greengrass 日志，以验证客户端设备是否成功连接和发送消息。有关更多信息，请参阅 [监控 AWS IoT Greengrass 日志](monitor-logs.md)。

## 测试通信（Java）
<a name="test-client-device-communications-java"></a>

在本节中，您将使用[适用于 Java 的AWS IoT Device SDK v2](https://github.com/aws/aws-iot-device-sdk-java-v2) 中的 Greengrass Discovery 示例来测试客户端设备与核心设备之间的通信。

**重要**  
要构建 Java 版 AWS IoT Device SDK v2，设备必须具有以下工具：  
Java 8 或更高版本，`JAVA_HOME` 指向 Java 文件夹。
Apache Maven

**测试通信（适用于 Java 的AWS IoT Device SDK v2）**

1. 下载并编译[适用于 Java 的AWS IoT Device SDKAWS IoT v2](https://github.com/aws/aws-iot-device-sdk-java-v2)，将其作为客户端设备进行连接。

   在客户端设备上，执行以下操作：

   1. 克隆适用于 Java 的 AWS IoT Device SDK v2 存储库进行下载。

      ```
      git clone https://github.com/aws/aws-iot-device-sdk-java-v2.git
      ```

   1. 切换到适用于 Java 的 AWS IoT Device SDK v2 文件夹。

   1. 编译适用于 Java 的 AWS IoT Device SDK v2。

      ```
      cd aws-iot-device-sdk-java-v2
      mvn versions:use-latest-versions -Dincludes="software.amazon.awssdk.crt*"
      mvn clean install
      ```

1. <a name="test-client-device-communications-application-scanner-intro"></a>运行示例 Greengrass Discovery 应用程序。此应用程序需要指定客户端设备事物名称、要使用的 MQTT 主题以及用于验证和保护连接的证书的参数。以下示例订阅了 `clients/MyClientDevice1/hello/world` 主题，并将您在命令行中输入的消息发布至同一主题。<a name="test-client-device-communications-application-command-replace"></a>
   + 将的*MyClientDevice1*两个实例替换为客户端设备的事物名称。
   + *\$1HOME/certs/AmazonRootCA1.pem*替换为客户端设备上的 Amazon 根 CA 证书的路径。
   + *\$1HOME/certs/device.pem.crt*替换为客户端设备上设备证书的路径。
   + *\$1HOME/certs/private.pem.key*替换为客户端设备上私钥文件的路径。
   + *us-east-1*替换为客户端设备和核心设备的运行 AWS 区域 位置。

   ```
   DISCOVERY_SAMPLE_ARGS="--thing_name MyClientDevice1 \
     --topic 'clients/MyClientDevice1/hello/world' \
     --ca_file $HOME/certs/AmazonRootCA1.pem \
     --cert $HOME/certs/device.pem.crt \
     --key $HOME/certs/private.pem.key \
     --region us-east-1"
   
   mvn exec:java -pl samples/Greengrass/Discovery \
     -Dexec.mainClass=greengrass.BasicDiscovery \
     -Dexec.args="$DISCOVERY_SAMPLE_ARGS"
   ```

   <a name="test-client-device-communications-application-scanner-output-intro"></a>Discovery 示例应用程序订阅主题并提示您输入要发布的消息。

   ```
   Connecting to group ID greengrassV2-coreDevice-MyGreengrassCore, with thing arn arn:aws:iot:us-east-1:123456789012:thing/MyGreengrassCore, using endpoint 203.0.113.0:8883
   Started a clean session
   Enter the message you want to publish to topic clients/MyClientDevice1/hello/world and press Enter. Type 'exit' or 'quit' to exit this program:
   ```

   <a name="test-client-device-communications-application-troubleshooting"></a>如果应用程序输出的是错误，请参阅 [Greengrass 发现问题疑难解答](troubleshooting-client-devices.md#greengrass-discovery-issues)。

1. <a name="test-client-device-communications-application-scanner-input"></a>输入一条消息，例如 **Hello World\$1**。

   ```
   Enter the message you want to publish to topic clients/MyClientDevice1/hello/world and press Enter. Type 'exit' or 'quit' to exit this program:
   Hello World!
   ```

   <a name="test-client-device-communications-application-scanner-input-output"></a>如果输出显示应用程序收到了有关该主题的 MQTT 消息，则客户端设备可以成功地与核心设备通信。

   ```
   Message received on topic clients/MyClientDevice1/hello/world: Hello World!
   ```

   <a name="test-client-device-communications-application-view-core-logs"></a>您还可以查看核心设备上的 Greengrass 日志，以验证客户端设备是否成功连接和发送消息。有关更多信息，请参阅 [监控 AWS IoT Greengrass 日志](monitor-logs.md)。

# Greengrass 发现 API RESTful
<a name="greengrass-discover-api"></a>

AWS IoT Greengrass 提供了 `Discover` API 操作，客户端设备可以使用该操作来识别 Greengrass 核心设备可以连接的位置。客户端设备使用此数据平面操作来检索连接到 Greengrass 核心设备所需的信息，您可以将它们与 API 操作相关联。[BatchAssociateClientDeviceWithCoreDevice](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_BatchAssociateClientDeviceWithCoreDevice.html)当客户端设备上线时，它可以连接到 AWS IoT Greengrass 云服务并使用发现 API 来查找：
+ 每台关联的 Greengrass 核心设备的 IP 地址和端口。
+ 核心设备 CA 证书，客户端设备可以使用该证书对 Greengrass 核心设备进行身份验证。

**注意**  
客户端设备还可以使用中的发现客户端 AWS IoT Device SDK 来发现 Greengrass 核心设备的连接信息。发现客户端使用 Discovery API。有关更多信息，请参阅下列内容：  
[测试客户端设备通信](test-client-device-communications.md)
*开发者@@ [指南中的 Greengrass RESTful 发现 API](https://docs.aws.amazon.com/greengrass/v1/developerguide/gg-discover-api.html)。AWS IoT Greengrass Version 1 *

要使用此 API 操作，请将 HTTP 请求发送到 Greengrass 数据面板端点上的发现 API。此 API 端点具有以下格式。

```
https://greengrass-ats.iot.region.amazonaws.com:port/greengrass/discover/thing/thing-name
```

有关 AWS IoT Greengrass 发现 API 支持的终端节点列表 AWS 区域 和终端节点列表，请参阅中的[AWS IoT Greengrass V2 终端节点和配额*AWS 一般参考*](https://docs.aws.amazon.com/general/latest/gr/greengrassv2.html)。此 API 操作仅在 Greengrass 数据面板端点上可用。用于管理组件和部署的控制面板端点与数据面板端点不同。

**注意**  
 AWS IoT Greengrass V1 和的发现 API 相同 AWS IoT Greengrass V2。如果您有连接到 AWS IoT Greengrass V1 核心的客户端设备，则无需更改客户端设备上的代码即可将它们连接到 AWS IoT Greengrass V2 核心设备。*有关更多信息，请参阅《开发者指南》中的 [Greengrass RESTful Discovery API](https://docs.aws.amazon.com/greengrass/v1/developerguide/gg-discover-api.html)。AWS IoT Greengrass Version 1 *

**Topics**
+ [发现身份验证和授权](#greengrass-discover-auth)
+ [请求](#greengrass-discover-request)
+ [响应](#greengrass-discover-response)
+ [使用 cURL 测试 Discovery API](#greengrass-discover-test-request)

## 发现身份验证和授权
<a name="greengrass-discover-auth"></a>

要使用 Discovery API 检索连接信息，客户端设备必须将 TLS 双向身份验证和 X.509 客户端证书配合使用才能进行身份验证。有关更多信息，请参阅《AWS IoT Core 开发人员指南》**中的 [X.509 客户端证书](https://docs.aws.amazon.com/iot/latest/developerguide/x509-client-certs.html)。

客户端设备还必须具有执行 `greengrass:Discover` 操作的权限。以下示例 AWS IoT 策略允许名`MyClientDevice1`为 AWS IoT 的事物自行执行`Discover`。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "greengrass:Discover",
      "Resource": [
        "arn:aws:iot:us-west-2:123456789012:thing/MyClientDevice1"
      ]
    }
  ]
}
```

------

**重要**  
<a name="thing-policy-variable-not-supported"></a>核心设备或 Greengrass 数据面板操作的 AWS IoT 策略不支持[事物策略变量](https://docs.aws.amazon.com/iot/latest/developerguide/thing-policy-variables.html) (`iot:Connection.Thing.*`)。相反，您可以使用通配符来匹配多个名称相似的设备。例如，您可以指定 `MyGreengrassDevice*` 以匹配 `MyGreengrassDevice1`、`MyGreengrassDevice2` 等。

有关更多信息，请参阅《AWS IoT Core 开发人员指南》**中的 [AWS IoT Core 策略](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html)。

## 请求
<a name="greengrass-discover-request"></a>

请求包含标准 HTTP 标头，并已发送到 Greengrass 发现端点，如以下示例所示。

端口号取决于核心设备已配置为通过端口 8443 还是端口 443 发送 HTTPS 流量。有关更多信息，请参阅 [通过端口 443 或网络代理进行连接](configure-greengrass-core-v2.md#configure-alpn-network-proxy)。

**注意**  
这些示例使用 Amazon Trust Services（ATS）端点，该端点使用推荐的 ATS 根 CA 证书。终端节点必须与 CA 证书类型匹配。

端口 8443  

```
HTTP GET https://greengrass-ats.iot.region.amazonaws.com:8443/greengrass/discover/thing/thing-name
```

端口 443  

```
HTTP GET https://greengrass-ats.iot.region.amazonaws.com:443/greengrass/discover/thing/thing-name
```
在端口 443 上连接的客户端必须实现[应用层协议协商 (ALPN)](https://tools.ietf.org/html/rfc7301) TLS 扩展，并且必须在 `ProtocolNameList` 中作为 `ProtocolName` 传递 `x-amzn-http-ca`。更多信息，请参阅 *AWS IoT 开发人员指南*中的[协议](https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html)。

## 响应
<a name="greengrass-discover-response"></a>

成功后，响应标头中包含 HTTP 200 状态码，响应正文中包含发现响应文档。

**注意**  
由于 AWS IoT Greengrass V2 使用与相同的发现 API AWS IoT Greengrass V1，因此响应会根据 AWS IoT Greengrass V1 概念（例如 Greengrass 群组）来组织信息。响应中包含 Greengrass 组的列表。在中 AWS IoT Greengrass V2，每台核心设备都位于自己的组中，该组中仅包含该核心设备及其连接信息。

### 示例发现响应文档
<a name="greengrass-discover-response-examples"></a>

以下文档显示了与一个 Greengrass 核心设备关联的客户端设备的响应。核心设备拥有一个端点和一个 CA 证书。

```
{
  "GGGroups": [
    {
      "GGGroupId": "greengrassV2-coreDevice-core-device-01-thing-name",
      "Cores": [
        {
          "thingArn": "core-device-01-thing-arn",
          "Connectivity": [
            {
              "id": "core-device-01-connection-id",
              "hostAddress": "core-device-01-address",
              "portNumber": core-device-01-port,
              "metadata": "core-device-01-description"
            }
          ]
        }
      ],
      "CAs": [
        "-----BEGIN CERTIFICATE-----cert-contents-----END CERTIFICATE-----"
      ]
    }
  ]
}
```

以下文档显示了与两个核心设备关联的客户端设备的响应。核心设备拥有多个端点和多个组 CA 证书。

```
{
  "GGGroups": [
    {
      "GGGroupId": "greengrassV2-coreDevice-core-device-01-thing-name",
      "Cores": [
        {
          "thingArn": "core-device-01-thing-arn",
          "Connectivity": [
            {
              "id": "core-device-01-connection-id",
              "hostAddress": "core-device-01-address",
              "portNumber": core-device-01-port,
              "metadata": "core-device-01-connection-1-description"
            },
            {
              "id": "core-device-01-connection-id-2",
              "hostAddress": "core-device-01-address-2",
              "portNumber": core-device-01-port-2,
              "metadata": "core-device-01-connection-2-description"
            }
          ]
        }
      ],
      "CAs": [
        "-----BEGIN CERTIFICATE-----cert-contents-----END CERTIFICATE-----",
        "-----BEGIN CERTIFICATE-----cert-contents-----END CERTIFICATE-----",
        "-----BEGIN CERTIFICATE-----cert-contents-----END CERTIFICATE-----"
      ]
    },
    {
      "GGGroupId": "greengrassV2-coreDevice-core-device-02-thing-name",
      "Cores": [
        {
          "thingArn":"core-device-02-thing-arn",
          "Connectivity" : [
            {
              "id": "core-device-02-connection-id",
              "hostAddress": "core-device-02-address",
              "portNumber": core-device-02-port,
              "metadata": "core-device-02-connection-1-description"
            }
          ]
        }
      ],
      "CAs": [
        "-----BEGIN CERTIFICATE-----cert-contents-----END CERTIFICATE-----",
        "-----BEGIN CERTIFICATE-----cert-contents-----END CERTIFICATE-----",
        "-----BEGIN CERTIFICATE-----cert-contents-----END CERTIFICATE-----"
      ]
    }
  ]
}
```

## 使用 cURL 测试 Discovery API
<a name="greengrass-discover-test-request"></a>

如果已安装 `cURL`，即可测试发现 API。以下示例指定了客户端设备的证书，用于对发往 Greengrass Discovery API 端点的请求进行身份验证。

```
curl -i \
  --cert 1a23bc4d56.cert.pem \
  --key 1a23bc4d56.private.key \
  https://greengrass-ats.iot.us-west-2.amazonaws.com:8443/greengrass/discover/thing/MyClientDevice1
```

**注意**  
`-i` 参数指定输出 HTTP 响应标头。您可以使用此选项来帮助识别错误。

如果请求成功，此命令将输出类似于以下示例的响应。

```
{
  "GGGroups": [
    {
      "GGGroupId": "greengrassV2-coreDevice-MyGreengrassCore",
      "Cores": [
        {
          "thingArn": "arn:aws:iot:us-west-2:123456789012:thing/MyGreengrassCore",
          "Connectivity": [
            {
              "Id": "AUTOIP_192.168.1.4_1",
              "HostAddress": "192.168.1.5",
              "PortNumber": 8883,
              "Metadata": ""
            }
          ]
        }
      ],
      "CAs": [
        "-----BEGIN CERTIFICATE-----\ncert-contents\n-----END CERTIFICATE-----\n"
      ]
    }
  ]
}
```

如果命令输出的是错误，请参阅 [Greengrass Discovery 问题疑难解答](troubleshooting-client-devices.md#greengrass-discovery-issues)。