使用 Azure IoT 中心将文件从设备上传到云 (.NET)

本文演示 IoT 中心的文件上传功能如何使用 Azure IoT .NET 设备和服务 SDK 将文件上传到 Azure Blob 存储

使用 IoT 中心发送云到设备的消息一文介绍了 IoT 中心提供的基本的云到设备的消息传送功能。 使用 IoT 中心配置消息路由一文介绍了一种在 Azure Blob 存储中可靠存储设备到云消息的方法。 但是,在某些情况下,无法轻松地将设备发送的数据映射为 IoT 中心接受的相对较小的设备到云消息。 例如:

  • 视频
  • 包含图像的大型文件
  • 以高频率采样的振动数据
  • 某种形式的预处理数据

通常使用 Azure 数据工厂Hadoop 堆栈等工具在云中批处理这些文件。 需要从设备上传文件时,仍可以使用 IoT 中心的安全性和可靠性。 本文介绍如何进行此操作。

在本文结束时,会运行两个 .NET 控制台应用:

  • FileUploadSample。 该设备应用使用 IoT 中心提供的 SAS URI 将文件上传到存储。 此示例来自你在先决条件中下载的 Azure IoT C# SDK 存储库中。

  • ReadFileUploadNotification。 此服务应用可接收来自 IoT 中心的文件上传通知。 你创建此应用。

注意

IoT 中心通过 Azure IoT 设备 SDK 来支持许多设备平台和语言(包括 C、Java、Python 和 JavaScript)。 请参阅 Azure IoT 开发人员中心,了解如何将设备连接到 Azure IoT 中心。

重要

使用 X.509 证书颁发机构 (CA) 身份验证的设备上的文件上传功能为公共预览版,并且必须启用预览模式。 这是在一同使用 X.509 指纹身份验证或 X.509 证书证明与 Azure 设备预配服务的设备上的正式发布版本。 若要了解有关使用 IoT 中心进行 x.509 身份验证的详细信息,请参阅支持的 x.509 证书

先决条件

  • Azure 订阅中的 IoT 中心。 如果还没有中心,则可以按照创建 IoT 中心中的步骤进行操作。

  • 在 IoT 中心注册的设备。 如果 IoT hub 中没有设备,请按照注册设备中的步骤操作。

  • 本文中运行的示例应用程序是使用 C# 和 .NET Core 编写的。

    .NET 下载适用于多个平台的 .NET Core SDK。

    使用以下命令验证开发计算机上 .NET Core SDK 的当前版本:

    dotnet --version
    
  • 下载示例下载 Azure IoT C# SDK,并提取 ZIP 存档。

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

将 Azure 存储帐户关联到 IoT 中心

若要从设备上传文件,必须拥有与 IoT 中心关联的 Azure 存储帐户和 Azure Blob 存储容器。 将存储帐户和容器与 IoT 中心关联后,IoT 中心可以在设备请求时提供 SAS URI 的元素。 然后,设备可以使用这些元素来构造 SAS URI,并将其用于向 Azure 存储进行身份验证,以及上传文件到 blob 容器。

将 Azure 存储帐户与 IoT 中心关联:

  1. 在“中心设置”下,选择 IoT 中心左侧窗格上的“文件上传”。

    显示从门户中选择“文件上传”设置的屏幕截图。

  2. 在“文件上传”窗格中,选择“Azure 存储容器” 。 对于本文,建议你的存储帐户和 IoT 中心位于同一区域。

    • 如果你已有要使用的存储帐户,请从列表中选择它。

    • 若要创建新的存储帐户,请选择“+存储帐户”。 为该存储帐户命名,并确保其位置设置为 IoT 中心的同一区域,然后选择“确定” 。 将在 IoT 中心的同一资源组中创建新帐户。 部署完成后,从列表中选择“存储帐户”。

    选择“存储帐户”后,将打开“容器”窗格。

  3. 在“容器”窗格中,选择“blob 容器”。

    • 如果已有要使用的 blob 容器,请从列表中选择它,然后单击“选择”。

    • 然后选择“新建容器”以创建新的 blob 容器。 为新容器命名。 出于本文的目的,可以将其他所有字段保留为默认值。 选择“创建”。 部署完成后,从列表中选择“容器”,然后单击“选择”。

  4. 回到“文件上传”窗格,确保文件通知设置为“开启” 。 可将其他所有设置保留默认值。 选择“保存”并等待设置完成,然后进入下一部分。

    显示在门户中确认文件上传设置的屏幕截图。

有关如何创建 Azure 存储帐户的详细说明,请参阅创建存储帐户。 若要了解如何将存储帐户以及 blob 容器与 IoT 中心关联的详细信息,请参阅使用 Azure 门户配置文件上传

从设备应用上传文件

在本文中,你将使用之前从 Azure IoT C# SDK 存储库中下载的示例作为设备应用。 可以使用 Visual Studio、Visual Studio Code 或所选的文本编辑器打开下面的文件。

该示例位于提取 Azure IoT C# SDK 的文件夹中的 azure-iot-sdk-csharp/iothub/device/samples/getting started/FileUploadSample。

检查 FileUpLoadSample.cs 中的代码。 此文件包含主要示例逻辑。 创建 IoT 中心设备客户端后,它将遵循由三部分组成的标准过程,用于从设备上传文件:

  1. 此代码调用设备客户端上的 GetFileUploadSasUriAsync 方法,以从 IoT 中心获取 SAS URI:

    var fileUploadSasUriRequest = new FileUploadSasUriRequest
    {
        BlobName = fileName
    };
    
    // Lines removed for clarity
    
    FileUploadSasUriResponse sasUri = await _deviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest);
    Uri uploadUri = sasUri.GetBlobUri();
    
  2. 此代码使用 SAS URI 将文件上传到 Azure 存储。 在此示例中,它使用 SAS URI 创建 Azure 存储块 Blob 客户端,并上传文件:

    var blockBlobClient = new BlockBlobClient(uploadUri);
    await blockBlobClient.UploadAsync(fileStreamSource, new BlobUploadOptions());
    
  3. 此代码通知 IoT 中心已完成上传。 这会告知 IoT 中心它可以发布与上传相关联的资源 (SAS URI)。 如果启用了文件上传通知,IoT 中心会将通知消息发送到后端服务。

    var successfulFileUploadCompletionNotification = new FileUploadCompletionNotification
    {
        // Mandatory. Must be the same value as the correlation id returned in the sas uri response
        CorrelationId = sasUri.CorrelationId,
    
        // Mandatory. Will be present when service client receives this file upload notification
        IsSuccess = true,
    
        // Optional, user defined status code. Will be present when service client receives this file upload notification
        StatusCode = 200,
    
        // Optional, user-defined status description. Will be present when service client receives this file upload notification
        StatusDescription = "Success"
    };
    
    await _deviceClient.CompleteFileUploadAsync(successfulFileUploadCompletionNotification);
    

如果你检查 parameter.cs 文件,会看到:

  • 该示例要求传递参数 p,该参数采用设备连接字符串。

  • 默认情况下,设备示例使用 MQTT 协议来与 IoT 中心通信。 可以使用参数 t 更改此传输协议。 不管选择的项如何,Azure Blob 客户端始终使用 HTTPS 作为协议来上传文件 Azure 存储。

获取 IoT 中心连接字符串

在本文中,你将创建一项后端服务,用于从你的 IoT 中心接收文件上传通知消息。 若要接收文件上传通知消息,服务需要服务连接权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。

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

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

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

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

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

屏幕截图显示如何在 Azure 门户中从 IoT 中心检索连接字符串。

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

接收文件上传通知

本部分中的操作将创建一个 C# 控制台应用,用于接收来自 IoT 中心的文件上传通知消息。

  1. 打开一个命令窗口并转到你想要在其中创建项目的文件夹。 创建名为 ReadFileUploadNotifications 的文件夹,并将目录更改到该文件夹。

    mkdir ReadFileUploadNotification
    cd ReadFileUploadNotification
    
  2. 运行以下命令来创建 C# 控制台项目。 运行命令后,文件夹将包含 Program.cs 文件和 ReadFileUploadNotification.csproj 文件 。

    dotnet new console --language c#
    
  3. 运行以下命令来将 Microsoft.Azure.Devices 包添加到项目文件。 此包是 Azure IoT .NET 服务 SDK。

    dotnet add package Microsoft.Azure.Devices
    
  4. 打开 Program.cs 文件,并在文件的顶部添加以下语句:

    using Microsoft.Azure.Devices;
    
  5. 将以下字段添加到 Program 类。 将 {iot hub connection string} 占位符值替换为以前在获取 IoT 中心连接字符串中复制的 IoT 中心连接字符串:

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

    private async static void ReceiveFileUploadNotificationAsync()
    {
        var notificationReceiver = serviceClient.GetFileNotificationReceiver();
        Console.WriteLine("\nReceiving file upload notification from service");
        while (true)
        {
            var fileUploadNotification = await notificationReceiver.ReceiveAsync();
            if (fileUploadNotification == null) continue;
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Received file upload notification: {0}", 
              string.Join(", ", fileUploadNotification.BlobName));
            Console.ResetColor();
            await notificationReceiver.CompleteAsync(fileUploadNotification);
        }
    }
    

    请注意,此接收模式与用于从设备应用接收云到设备消息的模式相同。

  7. 最后,将 Main 方法中的行替换为以下行:

    Console.WriteLine("Receive file upload notifications\n");
    serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
    ReceiveFileUploadNotificationAsync();
    Console.WriteLine("Press Enter to exit\n");
    Console.ReadLine();
    

运行应用程序

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

  1. 首先,运行服务应用,以接收来自 IoT 中心的文件上传通知。 在 ReadFileUploadNotification 文件夹中的命令提示符下,运行以下命令:

    dotnet restore
    dotnet run
    

    应用启动并等待来自 IoT 中心的文件上传通知:

    Receive file upload notifications
    
    
    Receiving file upload notification from service
    Press Enter to exit
    
  2. 接下来,运行设备应用以将文件上传到 Azure 存储。 打开新命令提示符,并将文件夹更改为你在其中扩展 Azure IoT C# SDK 的文件夹下的 azure-iot-sdk-csharp\iothub\device\samples\getting started\FileUploadSample。 运行以下命令。 将第二个命令中的 {Your device connection string} 占位符值替换为在 IoT 中心注册设备时看到的设备连接字符串。

    dotnet restore
    dotnet run --p "{Your device connection string}"
    

    上传完成后,设备应用会有以下输出:

      Uploading file TestPayload.txt
      Getting SAS URI from IoT Hub to use when uploading the file...
      Successfully got SAS URI (https://contosostorage.blob.core.chinacloudapi.cn/contosocontainer/MyDevice%2FTestPayload.txt?sv=2018-03-28&sr=b&sig=x0G1Baf%2BAjR%2BTg3nW34zDNKs07p6dLzkxvZ3ZSmjIhw%3D&se=2021-05-04T16%3A40%3A52Z&sp=rw) from IoT Hub
      Uploading file TestPayload.txt using the Azure Storage SDK and the retrieved SAS URI for authentication
      Successfully uploaded the file to Azure Storage
      Notified IoT Hub that the file upload succeeded and that the SAS URI can be freed.
      Time to upload file: 00:00:01.5077954.
      Done.
    
  3. 请注意,服务应用显示它已收到文件上传通知:

    Receive file upload notifications
    
    
    Receiving file upload notification from service
    Press Enter to exit
    
    Received file upload notification: myDeviceId/TestPayload.txt
    

验证文件上传

可以使用门户查看所配置的存储容器中上传的文件:

  1. 在 Azure 门户中导航到存储帐户。

  2. 在存储帐户的左侧窗格中,选择“容器”。

  3. 选择已将文件上传到其中的容器。

  4. 选择与设备同名的文件夹。

  5. 选择已将文件上传到其中的 Blob。 在本文中,它是名为 TestPayload.txt 的 Blob。

    屏幕截图显示在 Azure 门户中选择已上传的文件。

  6. 在打开的页面上查看 Blob 属性。 可以选择“下载”,以将该文件下载到本地并查看其内容。

后续步骤

在本文中,你已学习了如何使用 IoT 中心的文件上传功能来简化从设备进行的文件上传。 可以继续通过以下文章了解此功能: