使用 IoT 中心将文件从设备上传到云 (Java)Upload files from your device to the cloud with IoT Hub (Java)

本教程的内容基于使用 IoT 中心发送云到设备的消息教程中所述的代码,介绍如何使用 IoT 中心的文件上传功能将文件上传到 Azure Blob 存储This tutorial builds on the code in the Send Cloud-to-Device messages with IoT Hub tutorial to show you how to use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. 本教程介绍如何:The tutorial shows you how to:

  • 安全提供具有 Azure blob URI 的设备,用于上传文件。Securely provide a device with an Azure blob URI for uploading a file.
  • 使用 IoT 中心文件上传通知触发处理应用后端中的文件。Use the IoT Hub file upload notifications to trigger processing the file in your app back end.

从设备将遥测数据发送到 IoT 中心快速入门和使用 IoT 中心发送云到设备的消息教程介绍了 IoT 中心提供的基本的设备到云和云到设备的消息传送功能。The Send telemetry from a device to an IoT hub quickstart and Send cloud-to-device messages with IoT Hub tutorial show the basic device-to-cloud and cloud-to-device messaging functionality of IoT Hub. 使用 IoT 中心配置消息路由教程介绍了一种在 Azure Blob 存储中可靠存储设备到云消息的方法。The Configure message routing with IoT Hub tutorial describes a way to reliably store device-to-cloud messages in Azure blob storage. 但是,在某些情况下,无法轻松地将设备发送的数据映射为 IoT 中心接受的相对较小的设备到云消息。However, in some scenarios you cannot easily map the data your devices send into the relatively small device-to-cloud messages that IoT Hub accepts. 例如:For example:

  • 包含图像的大型文件Large files that contain images
  • 视频Videos
  • 以高频率采样的振动数据Vibration data sampled at high frequency
  • 某种形式的预处理数据。Some form of preprocessed data.

通常使用 Azure 数据工厂Hadoop 堆栈等工具在云中批处理这些文件。These files are typically batch processed in the cloud using tools such as Azure Data Factory or the Hadoop stack. 需要从设备上传文件时,仍可以使用 IoT 中心的安全性和可靠性。When you need to upland files from a device, you can still use the security and reliability of IoT Hub.

在本教程的最后,将运行两个 Java 控制台应用:At the end of this tutorial you run two Java console apps:

  • simulated-device,这是 [使用 IoT 中心发送云到设备的消息] 教程中创建的应用的修改版本。simulated-device, a modified version of the app created in the [Send Cloud-to-Device messages with IoT Hub] tutorial. 该应用使用 IoT 中心提供的 SAS URI 将文件上传到存储。This app uploads a file to storage using a SAS URI provided by your IoT hub.
  • read-file-upload-notification,它可以接收来自 IoT 中心的文件上传通知。read-file-upload-notification, which receives file upload notifications from your IoT hub.

备注

IoT 中心通过 Azure IoT 设备 SDK 来支持许多设备平台和语言(包括 C、.NET 和 Javascript)。IoT Hub supports many device platforms and languages (including C, .NET, and Javascript) through Azure IoT device SDKs. 有关如何将设备连接到 Azure IoT 中心的分步说明,请参阅 Azure IoT 开发人员中心Refer to the Azure IoT Developer Center for step-by-step instructions on how to connect your device to Azure IoT Hub.

必备条件Prerequisites

  • Java SE 开发工具包 8Java SE Development Kit 8. 请确保在“长期支持” 下选择“Java 8” 以获取 JDK 8 的下载。Make sure you select Java 8 under Long-term support to get to downloads for JDK 8.

  • Maven 3Maven 3

  • 有效的 Azure 帐户。An active Azure account. (如果没有帐户,只需几分钟即可创建一个试用帐户。)(If you don't have an account, you can create a trial account in just a couple of minutes.)

  • 确保已在防火墙中打开端口 8883。Make sure that port 8883 is open in your firewall. 本文中的设备示例使用 MQTT 协议,该协议通过端口 8883 进行通信。The device sample in this article uses MQTT protocol, which communicates over port 8883. 在某些公司和教育网络环境中,此端口可能被阻止。This port may be blocked in some corporate and educational network environments. 有关解决此问题的更多信息和方法,请参阅连接到 IoT 中心(MQTT)For more information and ways to work around this issue, see Connecting to IoT Hub (MQTT).

将 Azure 存储帐户关联到 IoT 中心Associate an Azure Storage account to IoT Hub

由于模拟设备应用将文件上传到 Blob,因此必须拥有与 IoT 中心关联的 Azure 存储帐户。Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated with your IoT hub. 将 Azure 存储帐户与 IoT 中心相关联时,IoT 中心会生成一个 SAS URI。When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. 设备可以使用此 SAS URI 安全地将文件上传到 Blob 容器。A device can use this SAS URI to securely upload a file to a blob container. IoT 中心服务和设备 SDK 协调生成 SAS URI 的过程,并使其可供设备用来上传文件。The IoT Hub service and the device SDKs coordinate the process that generates the SAS URI and makes it available to a device to use to upload a file.

按照使用 Azure 门户配置文件上传中的说明进行操作。Follow the instructions in Configure file uploads using the Azure portal. 确保有一个 Blob 容器与 IoT 中心关联并且已启用文件通知。Make sure that a blob container is associated with your IoT hub and that file notifications are enabled.

在门户中启用文件通知

从设备应用上传文件Upload a file from a device app

本部分中的操作将会修改在使用 IoT 中心发送云到设备的消息中创建的设备应用,以便将文件上传到 IoT 中心。In this section, you modify the device app you created in Send Cloud-to-Device messages with IoT Hub to upload a file to IoT hub.

  1. 将一个图像文件复制到 simulated-device 文件夹并将其重命名为 myimage.pngCopy an image file to the simulated-device folder and rename it myimage.png.

  2. 使用文本编辑器打开 simulated-device\src\main\java\com\mycompany\app\App.java 文件。Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.

  3. 将变量声明添加到 App 类:Add the variable declaration to the App class:

    private static String fileName = "myimage.png";
    
  4. 若要处理文件上传状态回调消息,请将以下嵌套类添加到 App 类:To process file upload status callback messages, add the following nested class to the App class:

    // Define a callback method to print status codes from IoT Hub.
    protected static class FileUploadStatusCallBack implements IotHubEventCallback {
      public void execute(IotHubStatusCode status, Object context) {
        System.out.println("IoT Hub responded to file upload for " + fileName
            + " operation with status " + status.name());
      }
    }
    
  5. 若要将图像上传到 IoT 中心,请将以下方法添加 App 类,以便将图像上传到 IoT 中心:To upload images to IoT Hub, add the following method to the App class to upload images to IoT Hub:

    // Use IoT Hub to upload a file asynchronously to Azure blob storage.
    private static void uploadFile(String fullFileName) throws FileNotFoundException, IOException
    {
      File file = new File(fullFileName);
      InputStream inputStream = new FileInputStream(file);
      long streamLength = file.length();
    
      client.uploadToBlobAsync(fileName, inputStream, streamLength, new FileUploadStatusCallBack(), null);
    }
    
  6. 修改 main 方法以调用 uploadFile 方法,如以下代码片段中所示:Modify the main method to call the uploadFile method as shown in the following snippet:

    client.open();
    
    try
    {
      // Get the filename and start the upload.
      String fullFileName = System.getProperty("user.dir") + File.separator + fileName;
      uploadFile(fullFileName);
      System.out.println("File upload started with success");
    }
    catch (Exception e)
    {
      System.out.println("Exception uploading file: " + e.getCause() + " \nERROR: " + e.getMessage());
    }
    
    MessageSender sender = new MessageSender();
    
  7. 使用以下命令生成 simulated-device 应用并检查错误:Use the following command to build the simulated-device app and check for errors:

    mvn clean package -DskipTests
    

获取 IoT 中心连接字符串Get the IoT hub connection string

在本文中,你将创建一项后端服务,用于从你在将遥测数据从设备发送到 IoT 中心中创建的 IoT 中心接收文件上传通知消息。In this article you create a backend service to receive file upload notification messages from the IoT hub you created in Send telemetry from a device to an IoT hub. 若要接收文件上传通知消息,服务需要“服务连接”权限。 To receive file upload notification messages, your service needs the service connect permission. 默认情况下,每个 IoT 中心都使用名为 service 的共享访问策略创建,该策略授予此权限。By default, every IoT Hub is created with a shared access policy named service that grants this permission.

若要获取 service 策略的 IoT 中心连接字符串,请执行以下步骤:To get the IoT Hub connection string for the service policy, follow these steps:

  1. Azure 门户中,选择“资源组” 。In the Azure portal, select Resource groups. 选择中心所在的资源组,然后从资源列表中选择中心。Select the resource group where your hub is located, and then select your hub from the list of resources.

  2. 在 IoT 中心的左侧窗格中,选择“共享访问策略” 。On the left-side pane of your IoT hub, select Shared access policies.

  3. 从策略列表中选择“service” 策略。From the list of policies, select the service policy.

  4. 在“共享访问密钥” 下,选择“连接字符串 - 主密钥” 所对应的“复制”图标并保存该值。Under Shared access keys, select the copy icon for the Connection string -- primary key and save the value.

    显示如何检索连接字符串

有关 IoT 中心共享访问策略和权限的详细信息,请参阅访问控制和权限For more information about IoT Hub shared access policies and permissions, see Access control and permissions.

接收文件上传通知Receive a file upload notification

本部分中的操作将创建一个 Java 控制台应用,用于接收来自 IoT 中心的文件上传通知消息。In this section, you create a Java console app that receives file upload notification messages from IoT Hub.

  1. 在命令提示符下使用以下命令,创建名为 read-file-upload-notification 的 Maven 项目。Create a Maven project called read-file-upload-notification using the following command at your command prompt. 请注意,此命令是一条很长的命令:Note this command is a single, long command:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=read-file-upload-notification -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. 在命令提示符下,导航到新的 read-file-upload-notification 文件夹。At your command prompt, navigate to the new read-file-upload-notification folder.

  3. 使用文本编辑器打开 pom.xml 文件夹中的 read-file-upload-notification 文件,在 dependencies 节点中添加以下依赖项。Using a text editor, open the pom.xml file in the read-file-upload-notification folder and add the following dependency to the dependencies node. 这样即可使用应用程序中的 iothub-java-service-client 包来与 IoT 中心服务通信:Adding the dependency enables you to use the iothub-java-service-client package in your application to communicate with your IoT hub service:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-service-client</artifactId>
      <version>1.7.23</version>
    </dependency>
    

    备注

    可以使用 Maven 搜索检查是否有最新版本的 iot-service-clientYou can check for the latest version of iot-service-client using Maven search.

  4. 保存并关闭 pom.xml 文件。Save and close the pom.xml file.

  5. 使用文本编辑器打开 read-file-upload-notification\src\main\java\com\mycompany\app\App.java 文件。Using a text editor, open the read-file-upload-notification\src\main\java\com\mycompany\app\App.java file.

  6. 在该文件中添加以下 import 语句:Add the following import statements to the file:

    import com.microsoft.azure.sdk.iot.service.*;
    import java.io.IOException;
    import java.net.URISyntaxException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
  7. 将以下类级变量添加到 App 类。Add the following class-level variables to the App class. {Your IoT Hub connection string} 占位符值替换为先前在获取 IoT 中心连接字符串中复制的 IoT 中心连接字符串:Replace the {Your IoT Hub connection string} placeholder value with the IoT hub connection string that you copied previously in Get the IoT hub connection string:

    private static final String connectionString = "{Your IoT Hub connection string}";
    private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
    private static FileUploadNotificationReceiver fileUploadNotificationReceiver = null;
    
  8. 若要在控制台中列显有关文件上传的信息,请将以下嵌套类添加到 App 类:To print information about the file upload to the console, add the following nested class to the App class:

    // Create a thread to receive file upload notifications.
    private static class ShowFileUploadNotifications implements Runnable {
      public void run() {
        try {
          while (true) {
            System.out.println("Receive file upload notifications...");
            FileUploadNotification fileUploadNotification = fileUploadNotificationReceiver.receive();
            if (fileUploadNotification != null) {
              System.out.println("File Upload notification received");
              System.out.println("Device Id : " + fileUploadNotification.getDeviceId());
              System.out.println("Blob Uri: " + fileUploadNotification.getBlobUri());
              System.out.println("Blob Name: " + fileUploadNotification.getBlobName());
              System.out.println("Last Updated : " + fileUploadNotification.getLastUpdatedTimeDate());
              System.out.println("Blob Size (Bytes): " + fileUploadNotification.getBlobSizeInBytes());
              System.out.println("Enqueued Time: " + fileUploadNotification.getEnqueuedTimeUtcDate());
            }
          }
        } catch (Exception ex) {
          System.out.println("Exception reading reported properties: " + ex.getMessage());
        }
      }
    }
    
  9. 若要启动侦听文件上传通知的线程,请将以下代码添加到 main 方法:To start the thread that listens for file upload notifications, add the following code to the main method:

    public static void main(String[] args) throws IOException, URISyntaxException, Exception {
      ServiceClient serviceClient = ServiceClient.createFromConnectionString(connectionString, protocol);
    
      if (serviceClient != null) {
        serviceClient.open();
    
        // Get a file upload notification receiver from the ServiceClient.
        fileUploadNotificationReceiver = serviceClient.getFileUploadNotificationReceiver();
        fileUploadNotificationReceiver.open();
    
        // Start the thread to receive file upload notifications.
        ShowFileUploadNotifications showFileUploadNotifications = new ShowFileUploadNotifications();
        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.execute(showFileUploadNotifications);
    
        System.out.println("Press ENTER to exit.");
        System.in.read();
        executor.shutdownNow();
        System.out.println("Shutting down sample...");
        fileUploadNotificationReceiver.close();
        serviceClient.close();
      }
    }
    
  10. 保存并关闭 read-file-upload-notification\src\main\java\com\mycompany\app\App.java 文件。Save and close the read-file-upload-notification\src\main\java\com\mycompany\app\App.java file.

  11. 使用以下命令生成 read-file-upload-notification 应用并检查错误:Use the following command to build the read-file-upload-notification app and check for errors:

    mvn clean package -DskipTests
    

运行应用程序Run the applications

现在,已准备就绪,可以运行应用程序了。Now you are ready to run the applications.

read-file-upload-notification 文件夹中的命令提示符下运行以下命令:At a command prompt in the read-file-upload-notification folder, run the following command:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

simulated-device 文件夹中的命令提示符下运行以下命令:At a command prompt in the simulated-device folder, run the following command:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

以下屏幕截图显示 simulated-device 应用的输出:The following screenshot shows the output from the simulated-device app:

simulated-device 应用的输出

以下屏幕截图显示 read-file-upload-notification 应用的输出:The following screenshot shows the output from the read-file-upload-notification app:

read-file-upload-notification 应用的输出

可以使用门户查看所配置的存储容器中上传的文件:You can use the portal to view the uploaded file in the storage container you configured:

上传的文件

后续步骤Next steps

在本教程中,你已学习了如何使用 IoT 中心的文件上传功能来简化从设备进行的文件上传。In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from devices. 可以使用以下文章继续探索 IoT 中心功能和方案:You can continue to explore IoT hub features and scenarios with the following articles:

若要进一步探索 IoT 中心的功能,请参阅:To further explore the capabilities of IoT Hub, see: