使用 Azure IoT 中樞 將檔案從裝置上傳至雲端

本文會示範如何:

  • 使用 IoT 中樞 的檔案上傳功能,使用 Azure IoT 裝置和服務 SDK,將檔案上傳至 Azure Blob 儲存體。
  • 通知 IoT 中樞 檔案已成功上傳,並建立後端服務,以使用 Azure IoT 服務 SDK 從 IoT 中樞 接收檔案上傳通知。

在某些情況下,您無法輕鬆地將裝置傳送的數據對應到 IoT 中樞 接受的相對小型裝置到雲端訊息。 IoT 中樞 中的檔案上傳功能可讓您將大型或複雜的數據移至雲端。 例如:

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

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

本文旨在補充本文中參考的可執行 SDK 範例。

如需詳細資訊,請參閱

重要

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

必要條件

  • IoT 中樞。 某些 SDK 呼叫需要 IoT 中樞 主要 連接字串,因此請記下 連接字串。

  • 已註冊的裝置。 某些 SDK 呼叫需要裝置主要 連接字串,因此請記下 連接字串。

  • IoT 中樞 Service Connect 許可權 - 若要接收檔案上傳通知訊息,後端服務需要 Service Connect 許可權。 根據預設,每個 IoT 中樞都是透過授與此權限且名為服務的共用存取原則所建立。 如需詳細資訊,請參閱 連線到IoT中樞

  • 藉由連結 Azure 儲存體 帳戶Azure Blob 儲存體 容器,在IoT中樞中設定檔案上傳。 您可以使用 Azure 入口網站、Azure CLIAzure PowerShell 來設定這些設定。

概觀

本操作說明包含兩個區段:

  • 從裝置應用程式上傳檔案
  • 在後端應用程式中接收檔案上傳通知

從裝置應用程式上傳檔案

本節說明如何使用適用於 .NET 的 Azure IoT SDK 中的 DeviceClient 類別,將檔案從裝置上傳至 IoT 中樞

請遵循此程式,將檔案從裝置上傳至IoT中樞:

  1. 線上到IoT中樞
  2. 從IoT中樞取得SAS URI
  3. 將檔案上傳至 Azure 記憶體
  4. 通知IoT中樞檔案上傳狀態

線上到裝置

呼叫 CreateFromConnectionString 以連線到裝置。 傳遞裝置主要 連接字串。

AMQP 是預設傳輸通訊協定。

static string connectionString = "{device primary connection string}";
deviceClient = DeviceClient.CreateFromConnectionString(connectionString);

從IoT中樞取得SAS URI

呼叫 GetFileUploadSasUriAsync 以取得檔案上傳詳細數據。 SAS URI 會在下一個步驟中使用,將檔案從裝置上傳至 Blob 記憶體。

const string filePath = "TestPayload.txt";
using var fileStreamSource = new FileStream(filePath, FileMode.Open);
var fileName = Path.GetFileName(fileStreamSource.Name);
var fileUploadSasUriRequest = new FileUploadSasUriRequest
{
    BlobName = fileName
};

FileUploadSasUriResponse sasUri = await _deviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest, System.Threading.CancellationToken cancellationToken = default);
Uri uploadUri = sasUri.GetBlobUri();

將檔案上傳至 Azure 記憶體

若要將檔案上傳至 Azure 記憶體:

  1. 建立 blockBlobClient 物件,並傳遞檔案上傳 URI。

  2. 使用 UploadAsync 方法將檔案上傳至 Blob 記憶體,並傳遞 SAS URI。 您可以選擇性地新增 Blob 上傳選項和取消令牌參數。

Azure Blob 用戶端一律會使用 HTTPS 作為通訊協定,將檔案上傳至 Azure 儲存體。

在此範例中,BlockBlobClient會傳遞 SAS URI 來建立 Azure 儲存體 區塊 Blob 用戶端,並上傳檔案:

var blockBlobClient = new BlockBlobClient(uploadUri);
await blockBlobClient.UploadAsync(fileStreamSource, null, null);

通知IoT中樞檔案上傳狀態

使用 CompleteFileUploadAsync 通知 IoT 中樞裝置用戶端已完成上傳,並 傳遞 FileUploadCompletionNotification 物件。 旗 IsSuccess 標會指出上傳是否成功。 收到通知后,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);

SDK 檔案上傳範例

SDK 包含此 檔案上傳範例

在後端應用程式中接收檔案上傳通知

您可以建立後端服務,以接收來自IoT中樞的檔案上傳通知訊息。

ServiceClient 類別包含服務可用來接收檔案上傳通知的方法。

若要接收檔案上傳通知:

  1. 呼叫 CreateFromConnectionString 以連線到 IoT 中樞。 傳遞IoT中樞主要 連接字串。
  2. 建立 CancellationToken
  3. 呼叫 GetFileNotificationReceiver 以建立通知接收者。
  4. 搭配 ReceiveAsync 使用循環來等候檔案上傳通知。

例如:

using Microsoft.Azure.Devices;
static ServiceClient serviceClient;
static string connectionString = "{IoT hub connection string}";
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);

// Define the cancellation token
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;

// Create a notification receiver
var notificationReceiver = serviceClient.GetFileNotificationReceiver();
Console.WriteLine("\nReceiving file upload notification from service");

// Check for file upload notifications
while (true)
{
    var fileUploadNotification = await notificationReceiver.ReceiveAsync(token);
    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);
}

概觀

本操作說明包含兩個區段:

  • 從裝置應用程式上傳檔案
  • 在後端應用程式中接收檔案上傳通知

從裝置應用程式上傳檔案

本節說明如何使用適用於 Java 的 Azure IoT SDK 的 DeviceClient 類別,將檔案從裝置上傳至 IoT 中樞

請遵循此程式,將檔案從裝置上傳至IoT中樞:

  1. 線上到裝置
  2. 從IoT中樞取得SAS URI
  3. 將檔案上傳至 Azure 儲存體
  4. 將檔案上傳狀態通知傳送至IoT中樞

連線通訊協定

檔案上傳作業一律使用 HTTPS,但 DeviceClient 可以定義遙測、裝置方法和裝置對應項等其他服務的 IotHubClientProtocol

IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;

線上到裝置

使用裝置主要 連接字串 具現化 DeviceClient 以連線到裝置。

String connString = "{IoT hub connection string}";
DeviceClient client = new DeviceClient(connString, protocol);

從IoT中樞取得SAS URI

呼叫 getFileUploadSasUri 以取得 FileUploadSasUriResponse 物件。

FileUploadSasUriResponse 包含這些方法和傳回值。 傳回值可以傳遞至檔案上傳方法。

方法 傳回值
getCorrelationId() 相互關聯 ID
getContainerName() 容器名稱
getBlobName() Blob 名稱
getBlobUri() Blob URI

例如:

FileUploadSasUriResponse sasUriResponse = client.getFileUploadSasUri(new FileUploadSasUriRequest(file.getName()));

System.out.println("Successfully got SAS URI from IoT hub");
System.out.println("Correlation Id: " + sasUriResponse.getCorrelationId());
System.out.println("Container name: " + sasUriResponse.getContainerName());
System.out.println("Blob name: " + sasUriResponse.getBlobName());
System.out.println("Blob Uri: " + sasUriResponse.getBlobUri());

將檔案上傳至 Azure 儲存體

將 Blob URI 端點傳遞至 BlobClientBuilder.buildclient 以建立 BlobClient 物件。

BlobClient blobClient =
    new BlobClientBuilder()
        .endpoint(sasUriResponse.getBlobUri().toString())
        .buildClient();

呼叫 uploadFromFile 將檔案上傳至 Blob 記憶體。

String fullFileName = "Path of the file to upload";
blobClient.uploadFromFile(fullFileName);

將檔案上傳狀態通知傳送至IoT中樞

在檔案上傳嘗試之後,將上傳狀態通知傳送至IoT中樞。

建立 FileUploadCompletionNotification 物件。 correlationId傳遞和 isSuccess 檔案上傳成功狀態。 isSuccess true當檔案上傳成功時傳遞值,false但未成功。

FileUploadCompletionNotification 即使檔案上傳失敗,也必須呼叫 。 IoT 中樞具有固定數目的 SAS URI,可在任何指定時間處於作用中狀態。 完成檔案上傳之後,您應該釋放 SAS URI,以便產生其他 SAS URI。 如果 SAS URI 未透過此 API 釋出,則最終會根據 SAS URI 設定為在 IoT 中樞上生存的時間長度釋放自己。

此範例會傳遞成功狀態。

FileUploadCompletionNotification completionNotification = new FileUploadCompletionNotification(sasUriResponse.getCorrelationId(), true);
client.completeFileUpload(completionNotification);

關閉用戶端

client釋放資源。

client.closeNow();

在後端應用程式中接收檔案上傳通知

您可以建立後端應用程式來接收檔案上傳通知。

若要建立檔案上傳通知應用程式:

  1. 線上到IoT中樞服務用戶端
  2. 檢查檔案上傳通知

ServiceClient 類別包含服務可用來接收檔案上傳通知的方法。

線上到IoT中樞服務用戶端

建立 IotHubServiceClientProtocol 物件。 聯機會使用通訊 AMQPS 協定。

呼叫 createFromConnectionString 以連線到IoT中樞。 傳遞IoT中樞主要 連接字串。

private static final String connectionString = "{IoT hub primary connection string}";
private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
ServiceClient sc = ServiceClient.createFromConnectionString(connectionString, protocol);

檢查檔案上傳狀態

若要檢查檔案上傳狀態:

  1. 建立 getFileUploadNotificationReceiver 物件。
  2. 使用 open 連線到 IoT 中樞。
  3. 呼叫 接收 以檢查檔案上傳狀態。 這個方法會傳 回 fileUploadNotification 物件。 如果收到上傳通知,您可以使用 fileUploadNotification 方法來檢視上傳狀態字段

例如:

FileUploadNotificationReceiver receiver = sc.getFileUploadNotificationReceiver();
receiver.open();
FileUploadNotification fileUploadNotification = receiver.receive(2000);

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());
}
else
{
    System.out.println("No file upload notification");
}

// Close the receiver object
receiver.close();

SDK 檔案上傳範例

有兩個 Java 檔案上傳 範例

安裝套件

必須先安裝 azure-iot-device 連結庫,才能呼叫任何相關的程序代碼。

pip install azure-iot-device

azure.storage.blob 套件可用來執行檔案上傳。

pip install azure.storage.blob

從裝置應用程式上傳檔案

本節說明如何使用適用於 Python 的 Azure IoT SDK IoT SDK 的 IoTHubDeviceClient 類別,將檔案從裝置上傳至 IoT 中樞

請遵循此程式,將檔案從裝置上傳至IoT中樞:

  1. 線上到裝置
  2. 取得 Blob 記憶體資訊
  3. 將檔案上傳至 Blob 記憶體
  4. 通知IoT中樞上傳狀態

匯入程式庫

import os
from azure.iot.device import IoTHubDeviceClient
from azure.core.exceptions import AzureError
from azure.storage.blob import BlobClient

線上到裝置

若要連線到裝置:

  1. 呼叫 create_from_connection_string 以新增裝置主要 連接字串。

  2. 呼叫 connect 以連線裝置用戶端。

例如:

# Add your IoT hub primary connection string
CONNECTION_STRING = "{Device primary connection string}"
device_client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)

# Connect the client
device_client.connect()

取得 Blob 記憶體資訊

呼叫 get_storage_info_for_blob,以從IoT中樞取得連結 Azure 儲存體 帳戶的相關信息。 此資訊包括主機名稱、容器名稱、blob 名稱和 SAS 權杖。 方法 get_storage_info_for_blob 也會傳 correlation_id回 方法中使用的 notify_blob_upload_statuscorrelation_id是 IoT 中樞標記您要處理的 Blob 的方式。

# Get the storage info for the blob
PATH_TO_FILE = "{Full path to local file}"
blob_name = os.path.basename(PATH_TO_FILE)
blob_info = device_client.get_storage_info_for_blob(blob_name)

將檔案上傳至 Blob 記憶體

若要將檔案上傳至 Blob 記憶體:

  1. 使用 from_blob_url 從 Blob URL 建立 BlobClient 物件。
  2. 呼叫 upload_blob ,將檔案上傳至 Blob 記憶體。

此範例會blob_info剖析 結構,以建立用來初始化 BlobClientURL。 然後它會呼叫 upload_blob 以將檔案上傳至 Blob 記憶體。

try:
    sas_url = "https://{}/{}/{}{}".format(
        blob_info["hostName"],
        blob_info["containerName"],
        blob_info["blobName"],
        blob_info["sasToken"]
    )

    print("\nUploading file: {} to Azure Storage as blob: {} in container {}\n".format(file_name, blob_info["blobName"], blob_info["containerName"]))

    # Upload the specified file
    with BlobClient.from_blob_url(sas_url) as blob_client:
        with open(file_name, "rb") as f:
            result = blob_client.upload_blob(f, overwrite=True)
            return (True, result)

except FileNotFoundError as ex:
    # catch file not found and add an HTTP status code to return in notification to IoT hub
    ex.status_code = 404
    return (False, ex)

except AzureError as ex:
    # catch Azure errors that might result from the upload operation
    return (False, ex)

通知IoT中樞上傳狀態

使用 notify_blob_upload_status 通知IoT中樞 Blob 記憶體作業的狀態。 correlation_id傳遞 方法取得的 get_storage_info_for_blobcorrelation_id IoT 中樞會使用 來通知任何可能正在接聽檔案上傳工作狀態的通知的服務。

此範例會通知 IoT 中樞成功上傳檔案:

device_client.notify_blob_upload_status(storage_info["correlationId"], True, 200, "OK: {}".format(PATH_TO_FILE)

關閉裝置用戶端

關閉用戶端。 呼叫此方法之後,任何嘗試進一 步的用戶端呼叫都會導致引發 ClientError

device_client.shutdown()

SDK 檔案上傳範例

SDK 包含兩個檔案上傳範例:

概觀

本操作說明包含兩個區段:

  • 從裝置應用程式上傳檔案
  • 在後端應用程式中接收檔案上傳通知

從裝置應用程式上傳檔案

本節說明如何使用適用於 Node.js 的 Azure IoT SDK 中的 azure-iot-device 套件,將檔案從裝置上傳至 IoT 中樞

安裝 SDK 套件

執行此命令以在 開發計算機上安裝 azure-iot-device SDK、 azure-iot-device-mqtt@azure/storage-blob 套件:

npm install azure-iot-device azure-iot-device-mqtt @azure/storage-blob --save

azure-iot-device 套件 包含與 IoT 裝置互動的物件。

請遵循此程式,將檔案從裝置上傳至IoT中樞:

  1. 取得 Blob 共用存取簽章
  2. 將檔案上傳至 Azure 儲存體
  3. 將檔案上傳狀態通知傳送至IoT中樞

建立模組

使用已安裝的套件建立客戶端、通訊協定、錯誤和路徑模組。

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');

從IoT中樞取得SAS URI

使用 getBlobSharedAccessSignature 從 IoT 中樞取得連結的記憶體帳戶 SAS 令牌。 如必要條件中所述,IoT 中樞會連結至 Blob 記憶體。

例如:

// make sure you set these environment variables prior to running the sample.
const localFilePath = process.env.PATH_TO_FILE;
const storageBlobName = path.basename(localFilePath);
const blobInfo = await client.getBlobSharedAccessSignature(storageBlobName);
if (!blobInfo) {
throw new errors.ArgumentError('Invalid upload parameters');
}

將檔案上傳至IoT中樞

若要將檔案從裝置上傳至IoT中樞:

  1. 建立數據流管線
  2. 建構 Blob URL
  3. 建立 BlockBlobClient 以將檔案上傳至 Blob 記憶體
  4. 呼叫 uploadFile 將檔案上傳至 Blob 記憶體
  5. 呼叫 notifyBlobUploadStatus 以通知 IoT 中樞上傳成功或失敗

例如:

// Open the pipeline
const pipeline = newPipeline(new AnonymousCredential(), {
retryOptions: { maxTries: 4 },
telemetry: { value: 'HighLevelSample V1.0.0' }, // Customized telemetry string
keepAliveOptions: { enable: false }
});

// Construct the blob URL
const { hostName, containerName, blobName, sasToken } = blobInfo;
const blobUrl = `https://${hostName}/${containerName}/${blobName}${sasToken}`;

// Create the BlockBlobClient for file upload to Blob Storage
const blobClient = new BlockBlobClient(blobUrl, pipeline);

// Setup blank status notification arguments to be filled in on success/failure
let isSuccess;
let statusCode;
let statusDescription;

const uploadStatus = await blobClient.uploadFile(localFilePath);
console.log('uploadStreamToBlockBlob success');

  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);
  }

// Send file upload status notification to IoT hub
await client.notifyBlobUploadStatus(blobInfo.correlationId, isSuccess, statusCode, statusDescription);

在後端應用程式中接收檔案上傳通知

您可以建立後端應用程式,以檢查 IoT 中樞服務用戶端是否有裝置檔案上傳通知。

若要建立檔案上傳通知應用程式:

  1. 線上到IoT中樞服務用戶端
  2. 檢查檔案上傳通知

線上到IoT中樞服務用戶端

ServiceClient 類別包含服務可用來接收檔案上傳通知的方法。

使用 fromConnectionString 連線到IoT中樞。 傳遞IoT中樞主要 連接字串。

const Client = require('azure-iothub').Client;
const connectionString = "{IoT hub primary connection string}";
const serviceClient = Client.fromConnectionString(connectionString);

開啟 IoT中樞的連線。

//Open the connection to IoT hub
serviceClient.open(function (err) {
  if (err) {
    console.error('Could not connect: ' + err.message);
  } else {
    console.log('Service client connected');

檢查檔案上傳通知

若要檢查檔案上傳通知:

  1. 呼叫 getFileNotificationReceiver。 提供收到通知訊息時所呼叫的檔案上傳回呼方法名稱。
  2. 在回呼方法中處理檔案上傳通知。

本範例會設定 receiveFileUploadNotification 通知回呼接收者。 接收者會解譯檔案上傳狀態資訊,並將狀態消息列印至主控台。

//Set up the receiveFileUploadNotification notification message callback receiver
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');
      }
    });
  });
}

SDK 檔案上傳範例

SDK 包含 上傳至 Blob 進階 範例。