计划和广播作业 (.NET)

使用 Azure IoT 中心来计划和跟踪可更新数百万台设备的作业。 使用作业可以:

  • 更新所需属性

  • 更新标记

  • 调用直接方法

一个作业包装上述一项操作,并跟踪一组设备中的执行进度(由设备孪生查询定义)。 例如,后端应用可以使用作业在 10,000 台设备上调用直接方法来重启设备。 使用设备孪生查询指定设备集,并将作业计划为在以后运行。 每个设备接收和执行“重新启动”直接方法时,该作业都会跟踪进度。

若要详细了解其中的每项功能,请参阅:

注意

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

本文介绍如何创建两个 .NET (C#) 控制台应用:

  • 一个设备应用 (SimulateDeviceMethods),它实现称为“LockDoor”的直接方法,后端应用可以调用该方法。

  • 一个后端应用 (ScheduleJob),它创建两个作业。 一个作业调用 lockDoor 直接方法,另一个作业将所需的属性更新发送到多个设备。

注意

有关可用于生成设备和后端应用的 SDK 工具的详细信息,请参阅 Azure IoT SDK

先决条件

  • Visual Studio。

  • IoT 中心。 使用 CLIAzure 门户创建一个。

  • 已注册的设备。 在 Azure 门户中注册一个。

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

创建模拟设备应用程序

在本部分中,会创建一个 .NET 控制台应用,用于响应解决方案后端调用的直接方法。

  1. 在 Visual Studio 中,选择“创建新项目”中,然后选择“控制台应用(.NET Framework)”项目模板 。 选择“下一步”继续。

  2. 在“配置新项目”中,将项目命名为 SimulateDeviceMethods,然后选择“下一步”。

    Screenshot of the 'Configure your new project' popup in Visual Studio.

  3. 接受.NET Framework 的默认版本,然后选择“创建”以创建项目。

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

  5. 在“NuGet 包管理器”中,选择“浏览”,然后搜索并选择“Microsoft.Azure.Devices.Client” 。 选择“安装” 。

    Screenshot of the NuGet Package Manager in Visual Studio.

    此步骤将下载、安装 Azure IoT 设备 SDK NuGet 包及其依赖项并添加对其的引用。

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

    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.Devices.Shared;
    using Newtonsoft.Json;
    using System.Threading.Tasks;
    using System.Text;
    
  7. 将以下字段添加到 Program 类。 将占位符值替换为上一部分中所述的设备连接字符串:

    static string DeviceConnectionString = "<yourDeviceConnectionString>";
    static DeviceClient Client = null;
    
  8. 添加以下代码,以在设备上实现直接方法:

    static Task<MethodResponse> LockDoor(MethodRequest methodRequest, object userContext)
    {
        Console.WriteLine();
        Console.WriteLine("Locking Door!");
        Console.WriteLine("\nReturning response for method {0}", methodRequest.Name);
    
        string result = "'Door was locked.'";
        return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
    }
    
  9. 添加以下方法,以在设备上实现设备孪生侦听程序:

    private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, 
      object userContext)
    {
        Console.WriteLine("Desired property change:");
        Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
    }
    
  10. 最后,将以下代码添加到 Main 方法,打开与 IoT 中心的连接并初始化方法侦听器:

    try
    {
        Console.WriteLine("Connecting to hub");
        Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, 
          TransportType.Mqtt);
    
        Client.SetMethodHandlerAsync("LockDoor", LockDoor, null);
        Client.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null);
    
        Console.WriteLine("Waiting for direct method call and device twin update\n Press enter to exit.");
        Console.ReadLine();
    
        Console.WriteLine("Exiting...");
    
        Client.SetMethodHandlerAsync("LockDoor", null, null);
        Client.CloseAsync().Wait();
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine("Error in sample: {0}", ex.Message);
    }
    
  11. 保存所做工作并构建解决方案。

注意

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

获取 IoT 中心连接字符串

在本文中,你将创建一项后端服务,该服务计划用于在设备上调用直接方法的作业及计划用于更新设备孪生的作业,并监视每个作业的进度。 若要执行这些操作,服务需要“注册表读取”和“注册表写入”权限。 默认情况下,每个 IoT 中心都使用名为 registryReadWrite的共享访问策略创建,该策略会授予这些权限。

若要获取 registryReadWrite策略的 IoT 中心连接字符串,请执行以下步骤:

  1. Azure 门户中,选择“资源组”。 选择中心所在的资源组,然后从资源列表中选择中心。

  2. 在中心的左侧窗格上,选择“共享访问策略”。

  3. 在策略列表中,选择“registryReadWrite”策略。

  4. 复制“主连接字符串”并保存该值。

    Screen capture that shows how to retrieve the connection string

有关 IoT 中心共享访问策略和权限的详细信息,请参阅访问控制和权限

计划用于调用直接方法和发送设备孪生更新的作业

本部分使用 C# 创建一个 .NET 控制台应用,该应用使用作业来调用 LockDoor 直接方法,并将所需属性更新发送到多个设备。

  1. 在 Visual Studio 中,选择“文件”>“新建”>“项目”。 在“创建新项目”中,选择“控制台应用(.NET Framework)”,然后选择“下一步” 。

  2. 在“配置新项目”中,将项目命名为 ScheduleJob,然后选择“创建”。

    Name and configure you ScheduleJob project

    Screenshot of the 'Configure your new project' popup in Visual Studio, where you add a name.

  3. 接受.NET Framework 的默认版本,然后选择“创建”以创建项目。

  4. 在“解决方案资源管理器”中,右键单击“ScheduleJob”项目,然后选择“管理 NuGet 程序包”。

  5. 在“NuGet 包管理器”中选择“浏览”,搜索并选择 Microsoft.Azure.Devices,然后选择“安装” 。

    此步骤将下载、安装 Azure IoT 服务 SDK NuGet 包及其依赖项并添加对其的引用。

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

    using Microsoft.Azure.Devices;
    using Microsoft.Azure.Devices.Shared;
    
  7. 如果默认语句中不存在下面的 using 语句,请添加该语句。

    using System.Threading;
    using System.Threading.Tasks;
    
  8. 将以下字段添加到 Program 类。 将占位符值替换为以前在获取 IoT 中心连接字符串中复制的 IoT 中心连接字符串以及设备的名称。

    static JobClient jobClient;
    static string connString = "<yourIotHubConnectionString>";
    static string deviceId = "<yourDeviceId>";
    
  9. 将以下方法添加到 Program 类:

    public static async Task MonitorJob(string jobId)
    {
        JobResponse result;
        do
        {
            result = await jobClient.GetJobAsync(jobId);
            Console.WriteLine("Job Status : " + result.Status.ToString());
            Thread.Sleep(2000);
        } while ((result.Status != JobStatus.Completed) && 
          (result.Status != JobStatus.Failed));
    }
    
  10. 将以下方法添加到 Program 类:

    public static async Task StartMethodJob(string jobId)
    {
        CloudToDeviceMethod directMethod = 
          new CloudToDeviceMethod("LockDoor", TimeSpan.FromSeconds(5), 
          TimeSpan.FromSeconds(5));
    
        JobResponse result = await jobClient.ScheduleDeviceMethodAsync(jobId,
            $"DeviceId IN ['{deviceId}']",
            directMethod,
            DateTime.UtcNow,
            (long)TimeSpan.FromMinutes(2).TotalSeconds);
    
        Console.WriteLine("Started Method Job");
    }
    
  11. 向 Program 类添加其他方法:

    public static async Task StartTwinUpdateJob(string jobId)
    {
        Twin twin = new Twin(deviceId);
        twin.Tags = new TwinCollection();
        twin.Tags["Building"] = "43";
        twin.Tags["Floor"] = "3";
        twin.ETag = "*";
    
        twin.Properties.Desired["LocationUpdate"] = DateTime.UtcNow;
    
        JobResponse createJobResponse = jobClient.ScheduleTwinUpdateAsync(
            jobId,
            $"DeviceId IN ['{deviceId}']", 
            twin, 
            DateTime.UtcNow, 
            (long)TimeSpan.FromMinutes(2).TotalSeconds).Result;
    
        Console.WriteLine("Started Twin Update Job");
    }
    

    注意

    有关查询语法的详细信息,请参阅 IoT 中心查询语言

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

    Console.WriteLine("Press ENTER to start running jobs.");
    Console.ReadLine();
    
    jobClient = JobClient.CreateFromConnectionString(connString);
    
    string methodJobId = Guid.NewGuid().ToString();
    
    StartMethodJob(methodJobId);
    MonitorJob(methodJobId).Wait();
    Console.WriteLine("Press ENTER to run the next job.");
    Console.ReadLine();
    
    string twinUpdateJobId = Guid.NewGuid().ToString();
    
    StartTwinUpdateJob(twinUpdateJobId);
    MonitorJob(twinUpdateJobId).Wait();
    Console.WriteLine("Press ENTER to exit.");
    Console.ReadLine();
    
  13. 保存所做工作并构建解决方案。

运行应用

现在可以运行应用了。

  1. 在 Visual Studio 的“解决方案资源管理器”中右键单击解决方案,然后选择“设置启动项目”。

  2. 选择“通用属性”>“启动项目”,然后选择“多启动项目”。

  3. 请确保 SimulateDeviceMethods 位于列表顶部且后接 ScheduleJob。 将这两项的操作均设置为“启动”,然后选择“确定” 。

  4. 单击“启动”以运行项目或转到“调试”菜单,然后单击“启动调试” 。

    会出现设备和后端应用的输出。

    Run the apps to schedule jobs

后续步骤

在本文中,你计划了作业来运行直接方法并更新设备孪生的属性。

若要继续完成 IoT 中心和设备管理模式(如远程无线固件更新)的入门内容,请阅读教程:如何进行固件更新