你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

设备管理入门

后端应用可使用 Azure IoT 中心基元(例如设备孪生直接方法)来远程启动和监视设备上的设备管理操作。

从后端应用程序使用直接方法来发起设备管理操作,例如重启、恢复出厂设置和固件更新。

设备负责以下操作:

  • 处理从 IoT 中心发送的直接方法请求
  • 在设备上发起相应的设备特定操作
  • 通过向 IoT 中心报告的属性,提供状态更新

本文介绍后端应用和设备应用如何协同工作,以便使用直接方法发起和监视远程设备操作。

  • 服务应用通过 IoT 中心调用直接方法,以在设备应用中执行重启操作。
  • 设备应用处理直接方法以重启设备。

注意

本文所述的功能只能用于 IoT 中心的标准层。 有关 IoT 中心基本层和标准/免费层的详细信息,请参阅选择适合你的解决方案的 IoT 中心层

注意

本文旨在补充本文中引用的 Azure IoT SDK 示例。 可使用 SDK 工具生成设备和后端应用程序。

先决条件

  • 一个 IoT 中心

  • 已注册的设备

  • 如果应用程序使用 MQTT 协议,请确保端口 8883 在防火墙中打开。 MQTT 协议通过端口 8883 进行通信。 在某些公司和教育网络环境中,此端口可能被阻止。 有关解决此问题的更多信息和方法,请参阅连接到 IoT 中心(MQTT)

  • 需要 Visual Studio

概述

本文介绍如何使用适用于 .NET 的 Azure IoT SDK,为设备直接消息创建设备和后端服务应用程序代码。

创建设备应用程序

本部分介绍如何使用设备应用程序代码创建直接方法回调侦听器。

所需的设备 NuGet 包

使用 C# 编写的设备客户端应用程序需要 NuGet 包“Microsoft.Azure.Devices.Client”

添加这些 using 语句以使用设备库。

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;

将设备连接到 IoT 中心

设备应用可以使用以下方法向 IoT 中心进行身份验证:

  • 共享访问密钥
  • X.509 证书

重要

本文包括使用共享访问签名(也称为对称密钥身份验证)连接设备的步骤。 此身份验证方法便于测试和评估,但使用 X.509 证书对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅“安全最佳做法 > 连接安全性”。

使用共享访问密钥进行身份验证

DeviceClient 类公开从设备与设备消息进行交互所需的所有方法。

使用 CreateFromConnectionString 方法以及设备连接字符串和连接传输协议连接到设备。

CreateFromConnectionString TransportType 传输协议参数支持以下传输协议:

  • Mqtt
  • Mqtt_WebSocket_Only
  • Mqtt_Tcp_Only
  • Amqp
  • Amqp_WebSocket_Only
  • Amqp_Tcp_Only
  • Http1

此示例使用 Mqtt 传输协议连接到设备。

static string DeviceConnectionString = "{IoT hub device connection string}";
static deviceClient = null;
deviceClient = DeviceClient.CreateFromConnectionString(DeviceConnectionString, 
   TransportType.Mqtt);

使用 X.509 证书进行身份验证

使用 X.509 证书将设备连接到 IoT 中心:

  1. 使用 DeviceAuthenticationWithX509Certificate 创建包含设备和证书信息的对象。 DeviceAuthenticationWithX509Certificate 将作为第二个参数传递给 DeviceClient.Create(步骤 2)。

  2. 使用 DeviceClient.Create 通过 X.509 证书将设备连接到 IoT 中心。

在此示例中,设备和证书信息将填充在传递给 DeviceClient.Createauth DeviceAuthenticationWithX509Certificate 对象中。

清楚起见,此示例以本地变量的形式显示证书输入参数值。 在生产系统中,请将敏感输入参数存储在环境变量中或其他更安全的存储位置。 例如,使用 Environment.GetEnvironmentVariable("HOSTNAME") 读取主机名环境变量。

RootCertPath = "~/certificates/certs/sensor-thl-001-device.cert.pem";
Intermediate1CertPath = "~/certificates/certs/sensor-thl-001-device.intermediate1.cert.pem";
Intermediate2CertPath = "~/certificates/certs/sensor-thl-001-device.intermediate2.cert.pem";
DevicePfxPath = "~/certificates/certs/sensor-thl-001-device.cert.pfx";
DevicePfxPassword = "1234";
DeviceName = "MyDevice";
HostName = "xxxxx.azure-devices.net";

var chainCerts = new X509Certificate2Collection();
chainCerts.Add(new X509Certificate2(RootCertPath));
chainCerts.Add(new X509Certificate2(Intermediate1CertPath));
chainCerts.Add(new X509Certificate2(Intermediate2CertPath));
using var deviceCert = new X509Certificate2(DevicePfxPath, DevicePfxPassword);
using var auth = new DeviceAuthenticationWithX509Certificate(DeviceName, deviceCert, chainCerts);

using var deviceClient = DeviceClient.Create(
    HostName,
    auth,
    TransportType.Amqp);

有关证书身份验证的详细信息,请参阅:

代码示例

有关设备 X.509 证书身份验证的工作示例,请参阅:

创建直接方法回调侦听器

使用 SetMethodHandlerAsync 初始化直接方法回调侦听器。 该侦听器与方法名称关键字(例如“reboot”)相关联。 在 IoT 中心或后端应用程序中,可使用方法名称来触发设备上的回调方法。

此示例设置一个名为 onReboot 的回调侦听器,该侦听器会在“reboot”直接方法名称调用时触发,

try
{
      // setup callback for "reboot" method
      deviceClient.SetMethodHandlerAsync("reboot", onReboot, null).Wait();
      Console.WriteLine("Waiting for reboot method\n Press enter to exit.");
      Console.ReadLine();

      Console.WriteLine("Exiting...");

      // as a good practice, remove the "reboot" handler
      deviceClient.SetMethodHandlerAsync("reboot", null, null).Wait();
      deviceClient.CloseAsync().Wait();
}
catch (Exception ex)
{
      Console.WriteLine();
      Console.WriteLine("Error in sample: {0}", ex.Message);
}

然后 onReboot 回调方法在设备上实现直接方法。

处理程序函数调用 MethodResponse 向调用应用程序发送响应确认消息。

static Task<MethodResponse> onReboot(MethodRequest methodRequest, object userContext)
{
      // In a production device, you would trigger a reboot 
      // scheduled to start after this method returns.
      // For this sample, we simulate the reboot by writing to the console
      // and updating the reported properties.
      try
      {
         Console.WriteLine("Rebooting!");
      }
      catch (Exception ex)
      {
         Console.WriteLine();
         Console.WriteLine("Error in sample: {0}", ex.Message);
      }

      string result = @"{""result"":""Reboot started.""}";
      return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
}

注意

为简单起见,本文不实现任何重试策略。 在生产代码中,应按暂时性故障处理中所述实现重试策略(例如指数退避)。

SDK 设备示例

适用于 .NET 的 Azure IoT SDK 提供了有效的设备应用示例,可用于处理直接方法任务。 有关详细信息,请参阅:

创建后端应用程序

本部分介绍如何在设备上触发直接方法。

ServiceClient 类公开创建后端应用程序以向设备发送直接方法调用所需的所有方法。

所需服务 NuGet 包

后端服务应用程序需要 NuGet 包“Microsoft.Azure.Devices”

添加这些 using 语句以使用服务库。

using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;

连接到 IoT 中心

可使用以下方法将后端服务连接到 IoT 中心:

  • 共享访问策略
  • Microsoft Entra

重要

本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 有关详细信息,请参阅安全最佳做法和云安全

使用共享访问策略进行连接

使用 CreateFromConnectionString 连接后端应用程序。

若要通过 IoT 中心在设备上调用直接方法,服务需要“服务连接”权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。

CreateFromConnectionString 的参数形式提供服务共享访问策略。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问

ServiceClient serviceClient;
string connectionString = "{IoT hub service shared access policy connection string}";
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);

使用 Microsoft Entra 进行连接

使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问

配置 Microsoft Entra 应用

必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:

  • 客户端机密
  • 证书
  • 联合标识凭据

根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问

有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台

使用 DefaultAzureCredential 进行身份验证

使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential 或精简的 ChainedTokenCredential。 为简单起见,本部分介绍如何使用 DefaultAzureCredential 和客户端机密进行身份验证。 有关使用 DefaultAzureCredential 的利弊的详细信息,请参阅 DefaultAzureCredential 的使用指南

DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。

Microsoft Entra 需要这些 NuGet 包和相应的 using 语句:

  • Azure.Core
  • Azure.Identity
using Azure.Core;
using Azure.Identity;

在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 将添加到环境变量中。 DefaultAzureCredential 使用这些环境变量对应用程序进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 IoT 中心连接方法的安全令牌凭据。

string clientSecretValue = "xxxxxxxxxxxxxxx";
string clientID = "xxxxxxxxxxxxxx";
string tenantID = "xxxxxxxxxxxxx";

Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", clientSecretValue);
Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientID);
Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantID);

TokenCredential tokenCredential = new DefaultAzureCredential();

然后可以将生成的 TokenCredential 传递给任何接受 Microsoft Entra 凭据的 SDK 客户端的 IoT 中心连接方法:

在此示例中,TokenCredential 将传递给 ServiceClient.Create,以创建 ServiceClient 连接对象。

string hostname = "xxxxxxxxxx.azure-devices.net";
using var serviceClient = ServiceClient.Create(hostname, tokenCredential, TransportType.Amqp);

在此示例中,TokenCredential 将传递给 RegistryManager.Create,以创建 RegistryManager 对象。

string hostname = "xxxxxxxxxx.azure-devices.net";
registryManager = RegistryManager.Create(hostname, tokenCredential);
代码示例

有关 Microsoft Entra 服务身份验证的有效示例,请参阅基于角色的身份验证示例

在设备上调用方法

在设备上调用方法:

  1. 创建 CloudToDeviceMethod 对象。 以参数形式传递设备直接方法名称。
  2. 调用 InvokeDeviceMethodAsync 以在设备上调用方法。

此示例调用“reboot”方法在设备上发起重启操作。 “reboot”方法将映射到设备上的侦听器,如本文创建直接方法回调侦听器部分中所述。

string targetDevice = "myDeviceId";
CloudToDeviceMethod method = new CloudToDeviceMethod("reboot");
method.ResponseTimeout = TimeSpan.FromSeconds(30);

CloudToDeviceMethodResult response = await serviceClient.InvokeDeviceMethodAsync(targetDevice, method);

Console.WriteLine("Invoked firmware update on device.");

SDK 服务示例

适用于 .NET 的 Azure IoT SDK 提供了有效的服务应用示例,可用于处理消息任务。 有关详细信息,请参阅:

概述

本文介绍如何使用适用于 Java 的 Azure IoT SDK,为设备直接方法创建设备和后端服务应用程序代码。

创建设备应用程序

本部分介绍如何使用设备应用程序代码创建直接方法回调侦听器。

DeviceClient 类公开与设备直接方法进行交互所需的所有方法。

重要

本文包括使用共享访问签名(也称为对称密钥身份验证)连接设备的步骤。 此身份验证方法便于测试和评估,但使用 X.509 证书对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅“安全最佳做法 > 连接安全性”。

设备导入语句

使用以下设备导入语句访问适用于 Java 的 Azure IoT SDK。

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.exceptions.IotHubClientException;
import com.microsoft.azure.sdk.iot.device.twin.DirectMethodPayload;
import com.microsoft.azure.sdk.iot.device.twin.DirectMethodResponse;
import com.microsoft.azure.sdk.iot.device.twin.MethodCallback;
import com.microsoft.azure.sdk.iot.device.transport.IotHubConnectionStatus;
import com.microsoft.azure.sdk.iot.device.twin.SubscriptionAcknowledgedCallback;

将设备连接到 IoT 中心

设备应用可以使用以下方法向 IoT 中心进行身份验证:

  • 共享访问密钥
  • X.509 证书

重要

本文包括使用共享访问签名(也称为对称密钥身份验证)连接设备的步骤。 此身份验证方法便于测试和评估,但使用 X.509 证书对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅“安全最佳做法 > 连接安全性”。

使用共享访问密钥进行身份验证

连接到设备:

  1. 使用 IotHubClientProtocol 选择一个传输协议。 例如:

    IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
    
  2. 使用 DeviceClient 构造函数添加设备主连接字符串和协议。

    String connString = "{IoT hub device connection string}";
    DeviceClient client = new DeviceClient(connString, protocol);
    
  3. 使用 open 将设备连接到 IoT 中心。 如果客户端已打开,该方法将不执行任何操作。

    client.open(true);
    

使用 X.509 证书进行身份验证

使用 X.509 证书将设备连接到 IoT 中心:

  1. 使用 buildSSLContext 生成 SSLContext 对象。
  2. SSLContext 信息添加到 ClientOptions 对象。
  3. 使用 ClientOptions 信息调用 DeviceClient,以创建设备到 IoT 中心的连接。

清楚起见,此示例以本地变量的形式显示证书输入参数值。 在生产系统中,请将敏感输入参数存储在环境变量中或其他更安全的存储位置。 例如,使用 Environment.GetEnvironmentVariable("PUBLICKEY") 读取公钥证书字符串环境变量。

private static final String publicKeyCertificateString =
        "-----BEGIN CERTIFICATE-----\n" +
        "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
        "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
        "-----END CERTIFICATE-----\n";

//PEM encoded representation of the private key
private static final String privateKeyString =
        "-----BEGIN EC PRIVATE KEY-----\n" +
        "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
        "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
        "-----END EC PRIVATE KEY-----\n";

SSLContext sslContext = SSLContextBuilder.buildSSLContext(publicKeyCertificateString, privateKeyString);
ClientOptions clientOptions = ClientOptions.builder().sslContext(sslContext).build();
DeviceClient client = new DeviceClient(connString, protocol, clientOptions);

有关证书身份验证的详细信息,请参阅:

代码示例

有关设备 X.509 证书身份验证的工作示例,请参阅:

创建直接方法回调侦听器

使用 subscribeToMethods 初始化直接方法回调侦听器。 在终止连接前,subscribeToMethods 会一直侦听传入的直接方法。 接收每个直接方法调用的方法名称和有效负载。

侦听器应调用 DirectMethodResponse,向调用应用程序发送方法响应确认消息。

例如:

client.subscribeToMethods(
    (methodName, methodData, context) ->
    {
        System.out.println("Received a direct method invocation with name " + methodName + " and payload " + methodData.getPayloadAsJsonString());
        return new DirectMethodResponse(200, methodData);
    },
    null);
System.out.println("Successfully subscribed to direct methods");

注意

为简单起见,本文不实现任何重试策略。 在生产代码中,应按暂时性故障处理中所述实现重试策略(例如指数退避)。

SDK 设备示例

适用于 Java 的 Azure IoT SDK 包含一个用于测试本文中所述的设备应用概念的工作示例。 有关详细信息,请参阅直接方法示例

创建后端应用程序

本部分介绍如何使用直接方法在设备上发起远程重启。

ServiceClient DeviceMethod 类包含服务可用于访问直接方法的方法。

服务导入语句

使用以下服务导入语句访问适用于 Java 的 Azure IoT SDK。

import com.microsoft.azure.sdk.iot.service.methods.DirectMethodRequestOptions;
import com.microsoft.azure.sdk.iot.service.methods.DirectMethodsClient;
import com.microsoft.azure.sdk.iot.service.methods.DirectMethodResponse;

连接到 IoT 中心

可使用以下方法将后端服务连接到 IoT 中心:

  • 共享访问策略
  • Microsoft Entra

重要

本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 有关详细信息,请参阅安全最佳做法和云安全

使用共享访问策略进行连接

使用 DeviceMethod 构造函数添加服务主连接字符串,并连接到 IoT 中心。

若要通过 IoT 中心在设备上调用直接方法,服务需要“服务连接”权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。

DeviceMethod 构造函数的参数形式,提供服务共享访问策略。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问

例如:

String iotHubConnectionString = "HostName=xxxxx.azure-devices.net;SharedAccessKeyName=service;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxx";
DeviceMethod methodClient = new DeviceMethod(iotHubConnectionString);

使用 Microsoft Entra 进行连接

使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问

有关 Java SDK 身份验证的概述,请参阅使用 Java 和 Azure 标识进行 Azure 身份验证

为简单起见,本部分重点介绍如何使用客户端机密进行身份验证。

配置 Microsoft Entra 应用

必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:

  • 客户端机密
  • 证书
  • 联合标识凭据

根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问

有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台

使用 DefaultAzureCredential 进行身份验证

使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential 或精简的 ChainedTokenCredential。 有关使用 DefaultAzureCredential 的利弊的详细信息,请参阅适用于 Java 的 Azure 标识客户端库中的凭据链

DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。

可以使用 DefaultAzureCredentialBuilder 来验证 Microsoft Entra 应用凭据。 客户端机密 tenantID、clientID 和客户端机密值等连接参数将保存为环境变量。 创建 TokenCredential 后,请将其作为“credential”参数传递给 ServiceClient 或其他生成器。

在此示例中,DefaultAzureCredentialBuilder 尝试根据 DefaultAzureCredential 中描述的列表对连接进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 ServiceClient 等构造函数的安全令牌凭据。

TokenCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build();
使用 ClientSecretCredentialBuilder 进行身份验证

可以使用 ClientSecretCredentialBuilder 来创建使用客户端机密信息的凭据。 如果成功,此方法将返回 TokenCredential,可将其作为“credential”参数传递给 ServiceClient 或其他生成器。

在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 值已添加到环境变量中。 ClientSecretCredentialBuilder 使用这些环境变量来生成凭据。

string clientSecretValue = System.getenv("AZURE_CLIENT_SECRET");
string clientID = System.getenv("AZURE_CLIENT_ID");
string tenantID = System.getenv("AZURE_TENANT_ID");

TokenCredential credential =
     new ClientSecretCredentialBuilder()
          .tenantId(tenantID)
          .clientId(clientID)
          .clientSecret(clientSecretValue)
          .build();
其他身份验证类

Java SDK 还包括以下使用 Microsoft Entra 对后端应用程序进行身份验证的类:

代码示例

有关 Microsoft Entra 服务身份验证的有效示例,请参阅基于角色的身份验证示例

在设备上调用方法

调用 DeviceMethod.invoke,以在设备上调用方法并返回结果状态。

invoke 有效负载参数为可选参数。 如果没有提供有效负载,请使用 null。 有效负载参数可采用不同的数据形式,包括字符串、字节数组和 HashMap。 有关示例,请参阅直接方法测试

此示例调用“reboot”方法在设备上发起重启操作。 “reboot”方法将映射到设备上的侦听器,如本文创建直接方法回调侦听器部分中所述。

例如:

String deviceId = "myFirstDevice";
String methodName = "reboot";
String payload = "Test payload";
Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);

MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout, payload);
if (result == null)
{
    throw new IOException("Method invoke returns null");
}
System.out.println("Status=" + result.getStatus());

SDK 服务示例

适用于 Java 的 Azure IoT SDK 提供了有效的服务应用示例,可用于处理直接方法任务。 有关详细信息,请参阅:

  • Python SDK - 建议使用 Python 3.7 或更高版本。 请确保根据安装程序的要求,使用 32 位或 64 位安装。 在安装过程中出现提示时,请确保将 Python 添加到特定于平台的环境变量中。

概述

本文介绍如何使用适用于 Python 的 Azure IoT SDK,为设备直接方法创建设备和后端服务应用程序代码。

安装包

必须安装 azure-iot-device 库才能创建设备应用程序

pip install azure-iot-device

必须安装 azure-iot-hub 库才能创建后端服务应用程序

pip install azure-iot-hub

创建设备应用程序

本部分介绍如何使用设备应用程序代码创建直接方法回调侦听器。

IoTHubDeviceClient 类包含可与直接方法一起使用的方法。

设备 import 语句

添加此 import 语句,以访问 IoTHubDeviceClientMethodResponse

# import the device client library
from azure.iot.device import IoTHubDeviceClient, MethodResponse

连接到设备

设备应用可以使用以下方法向 IoT 中心进行身份验证:

  • 共享访问密钥
  • X.509 证书

重要

本文包括使用共享访问签名(也称为对称密钥身份验证)连接设备的步骤。 此身份验证方法便于测试和评估,但使用 X.509 证书对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅“安全最佳做法 > 连接安全性”。

使用共享访问密钥进行身份验证

使用 create_from_connection_string 通过设备连接字符串将应用程序连接到设备。

# substitute the device connection string in conn_str
# and add it to the IoTHubDeviceClient object
conn_str = "{IoT hub device connection string}"
device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)

使用 X.509 证书进行身份验证

使用 X.509 证书将设备连接到 IoT 中心:

  1. 使用 create_from_x509_certificate 添加 X.509 证书参数
  2. 调用 connect 以连接设备客户端

清楚起见,此示例以本地变量的形式显示证书输入参数值。 在生产系统中,请将敏感输入参数存储在环境变量中或其他更安全的存储位置。 例如,使用 os.getenv("HOSTNAME") 读取主机名环境变量。

# The Azure IoT hub name
hostname = "xxxxx.azure-devices.net"

# The device that has been created on the portal using X509 CA signing or self-signing capabilities
device_id = "MyDevice"

# The X.509 certificate file name
cert_file = "~/certificates/certs/sensor-thl-001-device.cert.pfx"
key_file = "~/certificates/certs/sensor-thl-001-device.cert.key"
# The optional certificate pass phrase
pass_phrase = "1234"

x509 = X509(
    cert_file,
    key_file,
    pass_phrase,
)

# The client object is used to interact with your Azure IoT hub.
device_client = IoTHubDeviceClient.create_from_x509_certificate(
    hostname=hostname, device_id=device_id, x509=x509
)

# Connect to IoT Hub
await device_client.connect()

有关证书身份验证的详细信息,请参阅:

代码示例

有关设备 X.509 证书身份验证的工作示例,请参阅异步中心场景中文件名以 x509 结尾的示例。

创建直接方法回调

使用 on_method_request_received 创建接收直接方法时在设备上会调用的处理程序函数或协同例程。 该侦听器与方法名称关键字(例如“reboot”)相关联。 在 IoT 中心或后端应用程序中,可使用方法名称来触发设备上的回调方法。

处理程序函数应会创建 MethodResponse 并将其传递给 send_method_response,以向调用应用程序发送直接方法响应确认消息。

本示例将设置一个名为 method_request_handler 的直接方法处理程序。

try:
    # Attach the handler to the client
    client.on_method_request_received = method_request_handler
except:
    # In the event of failure, clean up
    client.shutdown()

在此示例中,method_request_handler 回调方法会在设备上实现直接方法。 从服务应用程序调用“rebootDevice”直接方法后,系统会执行此代码。 此方法调用 send_method_response,向调用应用程序发送直接方法响应确认消息。

# Define the handler for method requests
def method_request_handler(method_request):
    if method_request.name == "rebootDevice":
        # Act on the method by rebooting the device
        print("Rebooting device")
        time.sleep(20)
        print("Device rebooted")
        # Create a method response indicating the method request was resolved
        resp_status = 200
        resp_payload = {"Response": "This is the response from the device"}
        method_response = MethodResponse(method_request.request_id, resp_status, resp_payload)
    else:
        # Create a method response indicating the method request was for an unknown method
        resp_status = 404
        resp_payload = {"Response": "Unknown method"}
        method_response = MethodResponse(method_request.request_id, resp_status, resp_payload)

    # Send the method response
    client.send_method_response(method_response)

SDK 设备示例

适用于 Python 的 Azure IoT SDK 提供了有效的设备应用示例,可用于处理直接方法任务。 有关详细信息,请参阅接收直接方法

创建后端应用程序

本部分介绍如何使用后端服务应用程序在设备上调用直接方法。

IoTHubRegistryManager 类公开创建后端应用程序以将消息发送到设备所需的所有方法。

服务导入语句

添加这些 import 以连接到 Iot 中心、发送云到设备直接方法,然后接收设备直接方法响应。

from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import CloudToDeviceMethod, CloudToDeviceMethodResult

连接到 IoT 中心

可使用以下方法将后端服务连接到 IoT 中心:

  • 共享访问策略
  • Microsoft Entra

重要

本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 有关详细信息,请参阅安全最佳做法和云安全

使用共享访问策略进行连接

使用 from_connection_string 连接到 IoT 中心。

若要通过 IoT 中心在设备上调用直接方法,服务需要“服务连接”权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。

from_connection_string 的参数形式提供服务共享访问策略。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问

例如:

# Connect to IoT hub
IOTHUB_CONNECTION_STRING = "{IoT hub service connection string}"
iothub_registry_manager = IoTHubRegistryManager.from_connection_string(IOTHUB_CONNECTION_STRING)

使用 Microsoft Entra 进行连接

使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问

有关 Python SDK 身份验证的概述,请参阅使用 Azure SDK for Python 向 Azure 服务进行 Python 应用身份验证

配置 Microsoft Entra 应用

必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:

  • 客户端机密
  • 证书
  • 联合标识凭据

根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问

有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台

使用 DefaultAzureCredential 进行身份验证

使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential 或精简的 ChainedTokenCredential。 为简单起见,本部分介绍如何使用 DefaultAzureCredential 和客户端机密进行身份验证。 有关使用 DefaultAzureCredential 的利弊的详细信息,请参阅适用于 Python 的 Azure 标识客户端库中的凭据链

DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。

Microsoft Entra 需要此导入包和相应的 import 语句:

pip install azure-identity
from azure.identity import DefaultAzureCredential

在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 已添加到环境变量中。 DefaultAzureCredential 使用这些环境变量对应用程序进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 IoT 中心连接方法的安全令牌凭据。

from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()

然后可以将生成的 AccessToken 传递给 from_token_credential,以连接到任何接受 Microsoft Entra 凭据的 SDK 客户端的 IoT 中心:

from_token_credential 需要两个参数:

  • Azure 服务 URL - Azure 服务 URL 应采用 {Your Entra domain URL}.azure-devices.net 格式(不包括 https:// 前缀)。 例如,MyAzureDomain.azure-devices.net
  • Azure 凭据令牌

在此示例中,使用 DefaultAzureCredential 获取 Azure 凭据。 然后将 Azure 服务 URL 和凭据提供给 IoTHubRegistryManager.from_token_credential,以便与 IoT 中心创建连接。

import sys
import os

from azure.identity import DefaultAzureCredential
from azure.iot.hub import IoTHubRegistryManager

# Define the client secret values
clientSecretValue = 'xxxxxxxxxxxxxxx'
clientID = 'xxxxxxxxxxxxxx'
tenantID = 'xxxxxxxxxxxxx'

# Set environment variables
os.environ['AZURE_CLIENT_SECRET'] = clientSecretValue
os.environ['AZURE_CLIENT_ID'] = clientID
os.environ['AZURE_TENANT_ID'] = tenantID

# Acquire a credential object
credential = DefaultAzureCredential()

# Use Entra to authorize IoT Hub service
print("Connecting to IoTHubRegistryManager...")
iothub_registry_manager = IoTHubRegistryManager.from_token_credential(
url="MyAzureDomain.azure-devices.net",
token_credential=credential)
代码示例

有关 Microsoft Entra 服务身份验证的工作示例,请参阅适用于 Python 的 Microsoft 身份验证库 (MSAL)

在设备上调用方法

可以按设备上的名称调用直接方法。 方法名称可标识方法。 在以下设备示例和上面创建直接方法回调中的设备示例中,直接方法名称为“rebootDevice”。

在设备上调用直接方法:

  1. 创建 CloudToDeviceMethod 对象。 以参数形式提供方法名称和有效负载。
  2. 调用 invoke_device_method,以在设备上调用直接方法。 以参数形式提供设备 ID 和 CloudToDeviceMethod 有效负载对象。

此示例调用 CloudToDeviceMethod,以在设备上调用名为“rebootDevice”的直接方法。 成功调用直接方法后,系统会显示直接方法响应有效负载。

CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"

METHOD_NAME = "rebootDevice"
METHOD_PAYLOAD = "{\"method_number\":\"42\"}"
TIMEOUT = 60
WAIT_COUNT = 10

try:
    print ( "" )
    print ( "Invoking device to reboot..." )

    # Call the direct method.
    deviceMethod = CloudToDeviceMethod(method_name=METHOD_NAME, payload=METHOD_PAYLOAD)
    response = registry_manager.invoke_device_method(DEVICE_ID, deviceMethod)

    print ( "Successfully invoked the device to reboot." )

    print ( "The device has returned this payload:" )
    print ( response.payload )

except Exception as ex:
    print ( "" )
    print ( "Unexpected error {0}".format(ex) )
    return

SDK 服务示例

适用于 Python 的 Azure IoT SDK 提供了有效的服务应用示例,可用于处理直接方法任务。 有关详细信息,请参阅:

  • 需要 Node.js 10.0.x 版或更高版本

概述

本文介绍如何使用适用于 Node.js 的 Azure IoT SDK,为设备直接方法创建设备和后端服务应用程序代码。

创建设备应用程序

本部分介绍如何使用设备应用程序代码创建直接方法回调。

安装 SDK 包

azure-iot-device 包包含与 IoT 设备交互的对象。 运行以下命令,在开发计算机上安装“azure-iot-device”设备 SDK:

npm install azure-iot-device --save

将设备连接到 IoT 中心

设备应用可以使用以下方法向 IoT 中心进行身份验证:

  • X.509 证书
  • 共享访问密钥

重要

本文包括使用共享访问签名(也称为对称密钥身份验证)连接设备的步骤。 此身份验证方法便于测试和评估,但使用 X.509 证书对设备进行身份验证是一种更安全的方法。 若要了解详细信息,请参阅“安全最佳做法 > 连接安全性”。

使用 X.509 证书进行身份验证

X.509 证书将附加到设备到 IoT 中心的连接传输。

若要配置一个使用 X.509 证书的设备到 IoT 中心的连接,请执行以下操作:

  1. 调用 fromConnectionString,以将设备或标识模块连接字符串以及传输类型添加到 Client 对象。 将 x509=true 添加到连接字符串,以指示已将证书添加到 DeviceClientOptions。 例如:

    • 设备连接字符串

      HostName=xxxxx.azure-devices.net;DeviceId=Device-1;SharedAccessKey=xxxxxxxxxxxxx;x509=true

    • 标识模块连接字符串

      HostName=xxxxx.azure-devices.net;DeviceId=Device-1;ModuleId=Module-1;SharedAccessKey=xxxxxxxxxxxxx;x509=true

  2. 配置包含证书详细信息的 JSON 变量,并将其传递给 DeviceClientOptions

  3. 调用 setOptions,将 X.509 证书和密钥(以及可选的密码)添加到客户端传输。

  4. 调用 open 以打开从设备到 IoT 中心的连接。

此示例显示 JSON 变量中的证书配置信息。 认证配置 clientOptions 传递给 setOptions,并使用 open 打开连接。

const Client = require('azure-iot-device').Client;
const Protocol = require('azure-iot-device-mqtt').Mqtt;
// Connection string illustrated for demonstration only. Never hard-code the connection string in production. Instead use an environmental variable or other secure storage.
const connectionString = `HostName=xxxxx.azure-devices.net;DeviceId=Device-1;SharedAccessKey=xxxxxxxxxxxxx;x509=true`
const client = Client.fromConnectionString(connectionString, Protocol);

var clientOptions = {
   cert: myX509Certificate,
   key: myX509Key,
   passphrase: passphrase,
   http: {
     receivePolicy: {
       interval: 10
     }
   }
 }

 client.setOptions(clientOptions);
 client.open(connectCallback);

有关证书身份验证的详细信息,请参阅:

代码示例

有关设备 X.509 证书身份验证的工作示例,请参阅简单示例设备 X.509

使用共享访问密钥进行身份验证

选择传输协议

Client 对象支持以下属性:

  • Amqp
  • Http - 使用 Http 时,Client 实例不会频繁地检查来自 IoT 中心的消息(至少每 25 分钟一次)。
  • Mqtt
  • MqttWs
  • AmqpWs

在开发计算机上安装所需的传输协议。

例如,以下命令安装 Amqp 协议:

npm install azure-iot-device-amqp --save

有关 MQTT、AMQP 和 HTTPS 支持之间的差异的详细信息,请参阅云到设备通信指南选择通信协议

创建客户端对象

使用已安装的包创建 Client 对象。

例如:

const Client = require('azure-iot-device').Client;
创建协议对象

使用已安装的传输包创建 Protocol 对象。

此示例分配 AMQP 协议:

const Protocol = require('azure-iot-device-amqp').Amqp;
添加设备连接字符串和传输协议

调用 fromConnectionString 以提供设备连接参数:

  • connStr - 设备连接字符串。
  • transportCtor - 传输协议。

此示例使用 Amqp 传输协议:

const deviceConnectionString = "{IoT hub device connection string}"
const Protocol = require('azure-iot-device-mqtt').Amqp;
let client = Client.fromConnectionString(deviceConnectionString, Protocol);
打开到 IoT 中心的连接

使用 open 方法打开 IoT 设备与 IoT 中心之间的连接。

例如:

client.open(function(err) {
  if (err) {
    console.error('error connecting to hub: ' + err);
    process.exit(1);
  }
})

创建直接方法回调

调用 onDeviceMethod 创建接收直接方法时在设备上会调用的回调处理程序函数或协同例程。 该侦听器与方法名称关键字(例如“reboot”)相关联。 在 IoT 中心或后端应用程序中,可使用方法名称来触发设备上的回调方法。

回调处理程序函数应会调用 response.send 向调用应用程序发送响应确认消息。

此示例设置一个名为 onReboot 的直接方法处理程序,该处理程序会在“reboot”直接方法名称使用时调用。

client.onDeviceMethod('reboot', onReboot);

在此示例中,onReboot 回调方法会在设备上实现直接方法。 从服务应用程序调用“reboot”直接方法后,系统会执行此代码。 此函数会调用 response.send 向调用应用程序发送响应确认消息。

var onReboot = function(request, response) {

    // Respond the cloud app for the direct method
    response.send(200, 'Reboot started', function(err) {
        if (err) {
            console.error('An error occurred when sending a method response:\n' + err.toString());
        } else {
            console.log('Response to method \'' + request.methodName + '\' sent successfully.');
        }
    });

    // Add your device's reboot API for physical restart.
    console.log('Rebooting!');
};

SDK 设备示例

适用于 Node.js 的 Azure IoT SDK 提供了有效的设备应用示例,可用于处理设备管理任务。 有关详细信息,请参阅:

创建后端应用程序

本部分介绍如何在设备上调用直接方法。

安装服务 SDK 包

运行以下命令,在开发计算机上安装“azure-iothub”:

npm install azure-iothub --save

连接到 IoT 中心

可使用以下方法将后端服务连接到 IoT 中心:

  • 共享访问策略
  • Microsoft Entra

重要

本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 有关详细信息,请参阅安全最佳做法和云安全

使用共享访问策略进行连接

使用 fromConnectionString 连接到 IoT 中心。

若要通过 IoT 中心在设备上调用直接方法,服务需要“服务连接”权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。

CreateFromConnectionString 的参数的形式,提供服务共享访问策略连接字符串。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问

var Client = require('azure-iothub').Client;
var connectionString = '{IoT hub shared access policy connection string}';
var client = Client.fromConnectionString(connectionString);

使用 Microsoft Entra 进行连接

使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问

有关 Node.js SDK 身份验证的概述,请参阅:

配置 Microsoft Entra 应用

必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:

  • 客户端机密
  • 证书
  • 联合标识凭据

根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问

有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台

使用 DefaultAzureCredential 进行身份验证

使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential 或精简的 ChainedTokenCredential。 为简单起见,本部分介绍如何使用 DefaultAzureCredential 和客户端机密进行身份验证。 有关使用 DefaultAzureCredential 的利弊的详细信息,请参阅适用于 JavaScript 的 Azure 标识客户端库中的凭据链

DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。

Microsoft Entra 需要此包:

npm install --save @azure/identity

在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 已添加到环境变量中。 DefaultAzureCredential 使用这些环境变量对应用程序进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 IoT 中心连接方法的安全令牌凭据。

import { DefaultAzureCredential } from "@azure/identity";

// Azure SDK clients accept the credential as a parameter
const credential = new DefaultAzureCredential();

然后可以将生成的凭据令牌传递给 fromTokenCredential,以连接到任何接受 Microsoft Entra 凭据的 SDK 客户端的 IoT 中心:

fromTokenCredential 需要两个参数:

  • Azure 服务 URL - Azure 服务 URL 应采用 {Your Entra domain URL}.azure-devices.net 格式(不包括 https:// 前缀)。 例如,MyAzureDomain.azure-devices.net
  • Azure 凭据令牌

在此示例中,使用 DefaultAzureCredential 获取 Azure 凭据。 然后将 Azure 域 URL 和凭据提供给 Registry.fromTokenCredential,以便与 IoT 中心创建连接。

const { DefaultAzureCredential } = require("@azure/identity");

let Registry = require('azure-iothub').Registry;

// Define the client secret values
clientSecretValue = 'xxxxxxxxxxxxxxx'
clientID = 'xxxxxxxxxxxxxx'
tenantID = 'xxxxxxxxxxxxx'

// Set environment variables
process.env['AZURE_CLIENT_SECRET'] = clientSecretValue;
process.env['AZURE_CLIENT_ID'] = clientID;
process.env['AZURE_TENANT_ID'] = tenantID;

// Acquire a credential object
const credential = new DefaultAzureCredential()

// Create an instance of the IoTHub registry
hostName = 'MyAzureDomain.azure-devices.net';
let registry = Registry.fromTokenCredential(hostName,credential);
代码示例

有关 Microsoft Entra 服务身份验证的有效示例,请参阅 Azure 标识示例

在设备上调用方法

使用 invokeDeviceMethod 按设备上的名称调用直接方法。 方法名称参数可标识直接方法。

此示例调用“reboot”方法在设备上发起重启操作。 “reboot”方法将映射到设备上的回调处理程序函数,如本文创建直接方法回调部分中所述。

var startRebootDevice = function(deviceToReboot) {

    var methodName = "reboot";

    var methodParams = {
        methodName: methodName,
        payload: null,
        timeoutInSeconds: 30
    };

    client.invokeDeviceMethod(deviceToReboot, methodParams, function(err, result) {
        if (err) {
            console.error("Direct method error: "+err.message);
        } else {
            console.log("Successfully invoked the device to reboot.");  
        }
    });
};

SDK 服务示例

适用于 Node.js 的 Azure IoT SDK 提供了有效的服务应用示例,可用于处理设备管理任务。 有关详细信息,请参阅: