使用 Azure IoT 中樞 將檔案從您的裝置上傳至雲端(Node.js)

本文示範如何使用 Node.js 執行 IoT 中樞的檔案上傳功能,將檔案上傳至 Azure blob 儲存體

將遙測從裝置傳送至 IoT 中樞快速入門和使用 IoT 中樞傳送雲端到裝置訊息文章會示範 IoT 中樞的基本裝置到雲端和雲端到裝置傳訊功能。 使用 IoT 中樞設定訊息路由教學課程展示了如何在 Microsoft Azure Blob 儲存體中可靠地儲存裝置到雲端訊息。 不過,在某些情況下,您無法輕易地將裝置所傳送的資料對應至 IoT 中樞接受且相對較小的裝置到雲端的訊息。 例如:

  • 影片
  • 包含映像的大型檔案
  • 取樣高頻率的震動資料
  • 某種經前置處理的資料。

這些檔案通常會使用工具 (例如 Azure Data FactoryHadoop 堆疊) 在雲端中進行批次處理。 當您需要從裝置上傳檔案時,您仍然可以使用安全可靠的 IoT 中樞。 本文會說明如何操作。

在本文結尾處,您會執行兩個 Node.js 主控台應用程式:

  • FileUpload.js,其會使用 IoT 中樞提供的 SAS URI,將檔案上傳到儲存體。

  • FileUploadNotification.js,其會接收來自 IoT 中樞的檔案上傳通知。

注意

IoT 中樞透過 Azure IoT 裝置 SDK 來支援許多裝置平台和語言 (包括 C、Java、Python 及 JavaScript)。 若要了解如何將裝置連線至 Azure IoT 中樞,請參閱 Azure IoT 開發人員中心

重要

在使用 X.509 憑證授權 (CA) 驗證裝置上的檔案上傳功能目前為公開預覽狀態,請務必啟用預覽模式。 該功能已在以下裝置上正式發行:搭配 Azure 裝置佈建服務之使用 X.509 指紋驗證或 X.509 憑證證明的裝置。 若要深入了解使用 IoT 中樞的 X.509 驗證,請參閱支援的 X.509 憑證

必要條件

  • 一個 IoT 中樞。 使用 CLIAzure 入口網站建立一個。

  • 已註冊的裝置。 在 Azure 入口網站中註冊一個。

  • Node.js 10.0.x 版或更新版本。 建議使用 LTS 版本。 您可以從 nodejs.org (英文) 下載 Node.js。

  • 應該在您的防火牆中開放連接埠 8883。 本文中的裝置範例會使用 MQTT 通訊協定,其會透過連接埠 8883 進行通訊。 某些公司和教育網路環境可能會封鎖此連接埠。 如需此問題的詳細資訊和解決方法,請參閱連線至 IoT 中樞 (MQTT)

讓 Azure 儲存體帳戶與 IoT 中樞產生關聯

如果要從裝置上傳檔案,您必須擁有 Azure 儲存體帳戶及與 IoT 中樞相關聯的 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 入口網站設定檔案上傳

從裝置應用程式上傳檔案

在本節中,您可以建立裝置應用程式來將檔案上傳到 IoT 中樞。 程式碼是以 Azure IoT Node.js SDK (英文) 裝置範例中 upload_to_blob_advanced.js (英文) 範例的可用程式碼為基礎。

  1. 建立稱為 fileupload 的空資料夾。 在 fileupload 資料夾中,於命令提示字元使用下列命令建立 package.json 檔案。 接受所有預設值:

    npm init
    
  2. fileupload 資料夾中,於命令提示字元執行下列命令來安裝 azure-iot-device 裝置 SDK、azure-iot-device-mqtt 以及 @azure/storage-blob 套件:

    npm install azure-iot-device azure-iot-device-mqtt @azure/storage-blob --save
    
  3. 使用文字編輯器,在 fileupload 資料夾中建立 FileUpload.js 檔案,然後將下列程式碼複製到其中。

    'use strict';
    
    const Client = require('azure-iot-device').Client;
    const Protocol = require('azure-iot-device-mqtt').Mqtt;
    const errors = require('azure-iot-common').errors;
    const path = require('path');
    
    const {
      AnonymousCredential,
      BlockBlobClient,
      newPipeline
    } = require('@azure/storage-blob');
    
    // make sure you set these environment variables prior to running the sample.
    const deviceConnectionString = process.env.DEVICE_CONNECTION_STRING;
    const localFilePath = process.env.PATH_TO_FILE;
    const storageBlobName = path.basename(localFilePath);
    
    async function uploadToBlob(localFilePath, client) {
      const blobInfo = await client.getBlobSharedAccessSignature(storageBlobName);
      if (!blobInfo) {
        throw new errors.ArgumentError('Invalid upload parameters');
      }
    
      const pipeline = newPipeline(new AnonymousCredential(), {
        retryOptions: { maxTries: 4 },
        telemetry: { value: 'HighLevelSample V1.0.0' }, // Customized telemetry string
        keepAliveOptions: { enable: false }
      });
    
      // Construct the blob URL to construct the blob client for file uploads
      const { hostName, containerName, blobName, sasToken } = blobInfo;
      const blobUrl = `https://${hostName}/${containerName}/${blobName}${sasToken}`;
    
      // Create the BlockBlobClient for file upload to the Blob Storage Blob
      const blobClient = new BlockBlobClient(blobUrl, pipeline);
    
      // Setup blank status notification arguments to be filled in on success/failure
      let isSuccess;
      let statusCode;
      let statusDescription;
    
      try {
        const uploadStatus = await blobClient.uploadFile(localFilePath);
        console.log('uploadStreamToBlockBlob success');
    
        // Save successful status notification arguments
        isSuccess = true;
        statusCode = uploadStatus._response.status;
        statusDescription = uploadStatus._response.bodyAsText;
    
        // Notify IoT Hub of upload to blob status (success)
        console.log('notifyBlobUploadStatus success');
      }
      catch (err) {
        isSuccess = false;
        statusCode = err.code;
        statusDescription = err.message;
    
        console.log('notifyBlobUploadStatus failed');
        console.log(err);
      }
    
      await client.notifyBlobUploadStatus(blobInfo.correlationId, isSuccess, statusCode, statusDescription);
    }
    
    // Create a client device from the connection string and upload the local file to blob storage.
    const deviceClient = Client.fromConnectionString(deviceConnectionString, Protocol);
    uploadToBlob(localFilePath, deviceClient)
      .catch((err) => {
        console.log(err);
      })
      .finally(() => {
        process.exit();
      });
    
  4. 儲存並關閉 FileUpload.js 檔案。

  5. 將影像檔案複製到 fileupload 資料夾並為其命名,例如 myimage.png

  6. 為裝置連接字串新增環境變數,以及您要上傳之檔案的路徑。 當您在IoT中樞註冊裝置時 連接字串 裝置。

    • 若為 Windows:

      set DEVICE_CONNECTION_STRING={your device connection string}
      set PATH_TO_FILE={your image filepath}
      
    • 若為 Linux/Bash:

      export DEVICE_CONNECTION_STRING="{your device connection string}"
      export PATH_TO_FILE="{your image filepath}"
      

取得 IoT 中樞連接字串

在本文中,您將建立後端服務,接收來自所建立 IoT 中樞的檔案上傳通知訊息。 若要接收檔案上傳通知訊息,則服務需要服務連線權限。 根據預設,每個 IoT 中樞都是透過授與此權限且名為服務的共用存取原則所建立。

若要取得服務原則的 IoT 中樞連接字串,請遵循下列步驟:

  1. Azure 入口網站中,選取 [資源群組]。 選取中樞所在的資源群組,然後從資源清單選取中樞。

  2. 在 IoT 中樞的左側窗格中,選取 [共用存取原則]

  3. 從原則清單中,選取服務原則。

  4. 複製 [主要連接字串] 並儲存該值。

顯示如何在 Azure 入口網站 中擷取 IoT 中樞 連接字串 的螢幕快照。

如需 IoT 中樞共用存取原則和權限的詳細資訊,請參閱存取控制及權限

接收檔案上傳通知

在本節中,您要建立一個 Node.js 主控台應用程式,接收來自 IoT 中樞的檔案上傳通知訊息。

  1. 建立稱為 fileuploadnotification 的空資料夾。 在 fileuploadnotification 資料夾中,於命令提示字元使用下列命令建立 package.json 檔案。 接受所有預設值:

    npm init
    
  2. fileuploadnotification 資料夾中,於命令提示字元執行下列命令以安裝 azure-iothub SDK 套件:

    npm install azure-iothub --save
    
  3. 使用文字編輯器在 fileuploadnotification 資料夾中建立 FileUploadNotification.js 檔案。

  4. FileUploadNotification.js 檔案開頭新增下列 require 陳述式:

    'use strict';
    
    const Client = require('azure-iothub').Client;
    
  5. 從環境讀取 IoT 中樞的連接字串:

    const connectionString = process.env.IOT_HUB_CONNECTION_STRING;
    
  6. 新增下列程式碼,從連接字串建立服務用戶端:

    const serviceClient = Client.fromConnectionString(connectionString);
    
  7. 開啟用戶端,並使用 getFileNotificationReceiver 函式接收狀態更新。

    serviceClient.open(function (err) {
      if (err) {
        console.error('Could not connect: ' + err.message);
      } else {
        console.log('Service client connected');
        serviceClient.getFileNotificationReceiver(function receiveFileUploadNotification(err, receiver){
          if (err) {
            console.error('error getting the file notification receiver: ' + err.toString());
          } else {
            receiver.on('message', function (msg) {
              console.log('File upload from device:')
              console.log(msg.getData().toString('utf-8'));
              receiver.complete(msg, function (err) {
                if (err) {
                  console.error('Could not finish the upload: ' + err.message);
                } else {
                  console.log('Upload complete');
                }
              });
            });
          }
        });
      }
    });
    

    注意

    如果您想要在接聽檔案上傳通知時收到中斷連線通知,則必須以 'error' 註冊 receiver.on。 若要繼續接收檔案上傳通知,您必須使用 serviceClient.open 方法來重新連線至 IoT 中樞。

  8. 儲存並關閉 FileUploadNotification.js 檔案。

  9. 針對 IoT 中樞連接字串新增環境變數。 先前已於獲取 IoT 中樞連接字串中複製此字串。

    • 若為 Windows:

      set IOT_HUB_CONNECTION_STRING={your iot hub connection string}
      
    • 若為 Linux/Bash:

      export IOT_HUB_CONNECTION_STRING="{your iot hub connection string}"
      

執行應用程式

現在您已經準備好執行應用程式。

fileuploadnotification 資料夾的命令提示字元中,執行下列命令:

node FileUploadNotification.js

fileupload 資料夾的命令提示字元中,執行下列命令:

node FileUpload.js

上傳完成後,下列輸出來自 FileUpload 應用程式:

uploadStreamToBlockBlob success
notifyBlobUploadStatus success

下列範例輸出是在上傳完成後,來自 FileUploadNotification 應用程式:

Service client connected
File upload from device:
{"deviceId":"myDeviceId","blobUri":"https://{your storage account name}.blob.core.windows.net/device-upload-container/myDeviceId/image.png","blobName":"myDeviceId/image.png","lastUpdatedTime":"2021-07-23T23:27:06+00:00","blobSizeInBytes":26214,"enqueuedTimeUtc":"2021-07-23T23:27:07.2580791Z"}

確認檔案上傳

您可以使用入口網站檢視您所設定之儲存體容器中的上傳檔案:

  1. 在 Azure 入口網站中瀏覽至您的儲存體帳戶。

  2. 在儲存體帳戶的左窗格中,選取 [容器]

  3. 選取您上傳檔案的容器。

  4. 選取以您裝置命名的資料夾。

  5. 選取您要上傳檔案的 Blob。 在本文中,其為與您檔案同名的 Blob。

    在 Azure 入口網站 中檢視已上傳檔案的螢幕快照。

  6. 檢視開啟頁面上的 Blob 屬性。 您可以選取 [下載] 以下載檔案,並在本機檢視其內容。

下一步

在本文中,您已學到如何使用 IoT 中樞的檔案上傳功能來簡化從裝置上傳檔案。 您可以閱讀下列文章來繼續探索這個功能: