使用 .NET 将设备连接到 IoT 中心

简介

Azure IoT 中心是一项完全托管的 Azure 服务。 该服务可在数百万台物联网 (IoT) 设备和一个解决方案后端之间实现安全可靠的双向通信。 IoT 项目面临的最大挑战之一是如何可靠且安全地将设备连接到解决方案后端。 为了解决此难题,IoT 中心:

  • 提供可靠的设备到云和云到设备的超大规模消息传送。
  • 使用每个设备的安全凭据和访问控制来实现安全通信。
  • 包含最流行语言和平台的设备库。

本教程演示如何:

  • 使用 Azure 门户创建 IoT 中心。
  • 在 IoT 中心内创建设备标识。
  • 创建一个模拟设备,用于将遥测数据发送到解决方案后端。

本教程结束时,会创建三个 .NET 控制台应用:

  • CreateDeviceIdentity,用于创建设备标识和关联的安全密钥以连接设备应用。
  • ReadDeviceToCloudMessages,显示设备应用发送的遥测数据。
  • SimulatedDevice,它使用前面创建的设备标识连接到 IoT 中心,并使用 MQTT 协议每秒发送一次遥测消息。

按照本教程中的步骤从头创建示例应用。 也可从 Github 下载或克隆完成的 Visual Studio 解决方案:

git clone https://github.com/Azure-Samples/iot-hub-dotnet-simulated-device-client-app.git

Note

有关可用于生成在设备和解决方案后端上运行的应用程序的 Azure IoT SDK 的信息,请参阅 Azure IoT SDK

要完成本教程,需要以下各项:

  • Visual Studio 2015 或 Visual Studio 2017。
  • 有效的 Azure 帐户。 如果没有帐户,可以创建一个试用帐户,只需几分钟即可完成。

创建 IoT 中心

创建模拟设备应用要连接到的 IoT 中心。 以下步骤说明如何使用 Azure 门户来完成此任务。

  1. 登录到 Azure 门户

  2. 选择“新建” > “物联网” > “IoT 中心”。

    Azure 门户跳转栏

  3. 在“IoT 中心”窗格中,输入 IoT 中心的以下信息:

    • 名称:创建 IoT 中心的名称。 如果输入的名称有效,则显示一个绿色复选标记。

    Important

    IoT 中心将公开为 DNS 终结点,因此,命名时请务必避免包含任何敏感信息。

    • 定价和缩放级别:对于本教程,请选择F1 - 免费级别。 有关详细信息,请参阅定价和缩放层

    • 资源组:创建用于托管 IoT 中心的资源组,或使用现有的资源组。 有关详细信息,请参阅使用资源组管理 Azure 资源

    • 位置:选择最近的位置。

    • 固定仪表板:选中此选项可以方便地从仪表板访问 IoT 中心。

      IoT 中心窗口

  4. 单击“创建”。 创建 IoT 中心可能需要数分钟的时间。 可在“通知”窗格中监视进度。

  5. 新的 IoT 中心就绪以后,请在 Azure 门户中单击其磁贴,打开其属性窗口。 创建 IoT 中心以后,即可找到将设备和应用程序连接到 IoT 中心时需要使用的重要信息。 记下“主机名”,并单击“共享访问策略”。

    新建 IoT 中心窗口

  6. 在“共享访问策略”中,单击“iothubowner”策略,然后记下“iothubowner”窗口中的 IoT 中心连接字符串。 有关详细信息,请参阅“IoT 中心开发人员指南”中的访问控制

    共享访问策略

现已创建 IoT 中心,因此已具有完成本教程剩余部分所需的主机名和 IoT 中心连接字符串。

创建设备标识

在本部分中,会创建一个 .NET 控制台应用,用于在 IoT 中心的标识注册表中创建设备标识。 设备无法连接到 IoT 中心,除非它在标识注册表中具有条目。 有关详细信息,请参阅 IoT 中心开发人员指南的“标识注册表”部分。 运行此控制台应用时,它会生成唯一的设备 ID 和密钥。 设备在向 IoT 中心发送设备到云的消息时,使用这些值来标识自身。 设备 ID 区分大小写。

  1. 在 Visual Studio 中,使用“控制台应用(.NET Framework)”项目模板将 Visual C# Windows 经典桌面项目添加到新解决方案。 确保 .NET Framework 版本为 4.5.1 或更高。 将项目命名为 CreateDeviceIdentity,将解决方案命名为 IoTHubGetStarted

    新的 Visual C# Windows 经典桌面项目

  2. 在解决方案资源管理器中,右键单击“CreateDeviceIdentity”项目,然后单击“管理 NuGet 包”。

  3. 在“NuGet 包管理器”窗口中,选择“浏览”,搜索 microsoft.azure.devices,选择“安装”以安装 Microsoft.Azure.Devices 包,并接受使用条款。 此过程会下载、安装 Azure IoT 服务 SDK NuGet 包及其依赖项并添加对它的引用。

    “NuGet 包管理器”窗口

  4. Program.cs 文件顶部添加以下 using 语句:

    using Microsoft.Azure.Devices;
    using Microsoft.Azure.Devices.Common.Exceptions;
    
  5. 将以下字段添加到 Program 类。 将占位符值替换为在上一部分为中心创建的 IoT 中心连接字符串。

    static RegistryManager registryManager;
    static string connectionString = "{iot hub connection string}";
    
  6. 将以下方法添加到 Program 类:

    private static async Task AddDeviceAsync()
    {
      string deviceId = "myFirstDevice";
      Device device;
      try
      {
          device = await registryManager.AddDeviceAsync(new Device(deviceId));
      }
      catch (DeviceAlreadyExistsException)
      {
          device = await registryManager.GetDeviceAsync(deviceId);
      }
      Console.WriteLine("Generated device key: {0}", device.Authentication.SymmetricKey.PrimaryKey);
    }
    

    此方法会创建 ID 为 myFirstDevice的设备标识。 (如果该设备 ID 已在标识注册表中,代码就只检索现有的设备信息。)然后,应用程序会显示该标识的主密钥。 在模拟设备应用中使用此密钥连接到 IoT 中心。

    Important

    收集的日志中可能会显示设备 ID 用于客户支持和故障排除,因此,在为日志命名时,请务必避免包含任何敏感信息。

  7. 最后,在 Main 方法中添加以下行:

    registryManager = RegistryManager.CreateFromConnectionString(connectionString);
    AddDeviceAsync().Wait();
    Console.ReadLine();
    
  8. 运行此应用程序并记下设备密钥。

    应用程序生成的设备密钥

Note

IoT 中心标识注册表仅存储用于实现 IoT 中心安全访问的设备标识。 标识注册表存储用作安全凭据的设备 ID 和密钥。 标识注册表还为每个设备存储启用/禁用标志,该标志可以用于禁用对该设备的访问。 如果应用程序需要存储其他特定于设备的元数据,则应使用特定于应用程序的存储。 有关详细信息,请参阅 IoT 中心开发人员指南

接收设备到云的消息

本部分将创建一个 .NET 控制台应用,用于从 IoT 中心读取设备到云的消息。 IoT 中心公开与 Azure 事件中心兼容的终结点,以让用户读取设备到云的消息。 为了简单起见,本教程创建的基本读取器不适用于高吞吐量部署。 若要了解如何大规模处理设备到云的消息,请参阅处理设备到云的消息教程。 若要深入了解如何处理来自事件中心的消息,请参阅事件中心入门教程。 (本教程适用与 IoT 中心和事件中心相兼容的终结点。)

Note

读取设备到云消息的事件中心兼容终结点始终使用 AMQP 协议。

  1. 在 Visual Studio 中,使用“控制台应用(.NET Framework)”项目模板将 Visual C# Windows 经典桌面项目添加到当前解决方案。 确保 .NET Framework 版本为 4.5.1 或更高。 将项目命名为 ReadDeviceToCloudMessages

    新的 Visual C# Windows 经典桌面项目

  2. 在解决方案资源管理器中,右键单击“ReadDeviceToCloudMessages”项目,并单击“管理 NuGet 包”。
  3. 在“NuGet 包管理器”窗口中,搜索 WindowsAzure.ServiceBus,选择“安装”并接受使用条款。 该过程将下载、安装 Azure 服务总线及其所有依赖项并添加对它的引用。 此包可让应用程序连接到 IoT 中心上与事件中心兼容的终结点。
  4. Program.cs 文件顶部添加以下 using 语句:

    using Microsoft.ServiceBus.Messaging;
    using System.Threading;
    
  5. 将以下字段添加到 Program 类。 将占位符值替换为在“创建 IoT 中心”部分为中心创建的 IoT 中心连接字符串。

    static string connectionString = "{iothub connection string}";
    static string iotHubD2cEndpoint = "messages/events";
    static EventHubClient eventHubClient;
    
  6. 将以下方法添加到 Program 类:

     private static async Task ReceiveMessagesFromDeviceAsync(string partition, CancellationToken ct)
     {
         var eventHubReceiver = eventHubClient.GetDefaultConsumerGroup().CreateReceiver(partition, DateTime.UtcNow);
         while (true)
         {
             if (ct.IsCancellationRequested) break;
             EventData eventData = await eventHubReceiver.ReceiveAsync();
             if (eventData == null) continue;
    
             string data = Encoding.UTF8.GetString(eventData.GetBytes());
             Console.WriteLine("Message received. Partition: {0} Data: '{1}'", partition, data);
         }
     }
    

    此方法使用 EventHubReceiver 实例接收来自所有 IoT 中心设备到云接收分区的消息。 请注意在创建 EventHubReceiver 对象时传递 DateTime.Now 参数的方式,使它仅接收启动后发送的消息。 此筛选器在测试环境中非常有用,因为这样可以看到当前的消息集。 在生产环境中,代码应确保处理所有消息。 有关详细信息,请参阅教程如何处理 IoT 中心设备到云的消息

  7. 最后,在 Main 方法中添加以下行:

     Console.WriteLine("Receive messages. Ctrl-C to exit.\n");
     eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, iotHubD2cEndpoint);
    
     var d2cPartitions = eventHubClient.GetRuntimeInformation().PartitionIds;
    
     CancellationTokenSource cts = new CancellationTokenSource();
    
     System.Console.CancelKeyPress += (s, e) =>
     {
       e.Cancel = true;
       cts.Cancel();
       Console.WriteLine("Exiting...");
     };
    
     var tasks = new List<Task>();
     foreach (string partition in d2cPartitions)
     {
        tasks.Add(ReceiveMessagesFromDeviceAsync(partition, cts.Token));
     }  
     Task.WaitAll(tasks.ToArray());
    

创建设备应用

本部分将创建一个 .NET 控制台应用,用于模拟向 IoT 中心发送设备到云消息的设备。

  1. 在 Visual Studio 中,使用“控制台应用(.NET Framework)”项目模板将 Visual C# Windows 经典桌面项目添加到当前解决方案。 确保 .NET Framework 版本为 4.5.1 或更高。 将项目命名为 SimulatedDevice

    新的 Visual C# Windows 经典桌面项目

  2. 在解决方案资源管理器中,右键单击“SimulatedDevice”项目,并单击“管理 NuGet 包”。
  3. 在“NuGet 包管理器”窗口中,选择“浏览”,搜索 Microsoft.Azure.Devices.Client,选择“安装”以安装 Microsoft.Azure.Devices.Client 包,并接受使用条款。 该过程将下载、安装 Azure IoT 设备 SDK NuGet 包及其依赖项并添加对它的引用。
  4. Program.cs 文件顶部添加以下 using 语句:

    using Microsoft.Azure.Devices.Client;
    using Newtonsoft.Json;
    
  5. 将以下字段添加到 Program 类。 将 {iot hub hostname} 替换为在“创建 IoT 中心”部分检索的 IoT 中心主机名。 将 {device key} 替换为在“创建设备标识”部分检索的设备密钥。

    static DeviceClient deviceClient;
    static string iotHubUri = "{iot hub hostname}";
    static string deviceKey = "{device key}";
    
  6. 将以下方法添加到 Program 类:

     private static async void SendDeviceToCloudMessagesAsync()
     {
         double minTemperature = 20;
         double minHumidity = 60;
         int messageId = 1;
         Random rand = new Random();
    
         while (true)
         {
             double currentTemperature = minTemperature + rand.NextDouble() * 15;
             double currentHumidity = minHumidity + rand.NextDouble() * 20;
    
             var telemetryDataPoint = new
             {
                 messageId = messageId++,
                 deviceId = "myFirstDevice",
                 temperature = currentTemperature,
                 humidity = currentHumidity
             };
             var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
             var message = new Message(Encoding.ASCII.GetBytes(messageString));
             message.Properties.Add("temperatureAlert", (currentTemperature > 30) ? "true" : "false");
    
             await deviceClient.SendEventAsync(message);
             Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
    
             await Task.Delay(1000);
         }
     }
    

    此方法每隔一秒发送一条新的设备到云消息。 该消息包含一个具有设备 ID 的 JSON 序列化对象和一个随机生成的编号,用于模拟温度传感器和湿度传感器。

  7. 最后,在 Main 方法中添加以下行:

    Console.WriteLine("Simulated device\n");
    deviceClient = DeviceClient.Create(iotHubUri, new DeviceAuthenticationWithRegistrySymmetricKey("myFirstDevice", deviceKey), TransportType.Mqtt);
    deviceClient.ProductInfo = "HappyPath_Simulated-CSharp";
    SendDeviceToCloudMessagesAsync();
    Console.ReadLine();
    

    默认情况下,.NET Framework 应用中的 Create 方法将创建使用 AMQP 协议来与 IoT 中心通信的 DeviceClient 实例。 若要使用 MQTT 或 HTTPS 协议,请使用 Create 方法的重写,它使用户能够指定协议。 UWP 和 PCL 客户端默认使用 HTTPS 协议。 如果使用 HTTPS 协议,则还应在项目中添加 Microsoft.AspNet.WebApi.Client NuGet 包,以包含 System.Net.Http.Formatting 命名空间。

本教程逐步讲解如何创建 IoT 中心设备应用。 也可以使用 Azure IoT 中心的连接服务 Visual Studio 扩展将所需的代码添加到设备应用。

Note

为简单起见,本教程不实现任何重试策略。 在生产代码中,应该按 MSDN 文章 Transient Fault Handling(暂时性故障处理)中所述实施重试策略(例如指数性的回退)。

运行应用

现在,已准备就绪,可以运行应用。

  1. 在 Visual Studio 的“解决方案资源管理器”中右键单击解决方案,并单击“设置启动项目”。 选择“多个启动项目”,并针对“ReadDeviceToCloudMessages”和“SimulatedDevice”项目选择“启动”作为操作。

    启动项目属性

  2. F5 启动这两个应用,使其运行。 来自 SimulatedDevice 应用的控制台输出会显示设备应用发送到 IoT 中心的消息。 来自 ReadDeviceToCloudMessages 应用的控制台输出则会显示 IoT 中心接收的消息。

    来自应用的控制台输出

  3. Azure 门户中的“使用情况”磁贴显示发送到 IoT 中心的消息数:

    Azure 门户的“使用情况”磁贴

后续步骤

在本教程中,已在 Azure 门户中配置了 IoT 中心,并在 IoT 中心的标识注册表中创建了设备标识。 已使用此设备标识来让设备应用向 IoT 中心发送设备到云的消息。 还创建了一个应用,用于显示 IoT 中心接收的消息。

若要继续了解 IoT 中心入门知识并浏览其他 IoT 方案,请参阅:

若要了解如何扩展 IoT 解决方案和如何大规模处理设备到云的消息,请参阅 Process device-to-cloud messages (处理设备到云的消息)教程。

若要继续了解 Azure IoT 中心入门知识并浏览其他 IoT 方案,请参阅以下文章: