Azure IoT Hub を使用してデバイスからクラウドにファイルをアップロードする (.NET)

この記事では、Azure IoT .NET デバイスとサービス SDK を使って、IoT Hub のファイル アップロード機能でファイルを Azure BLOB ストレージにアップロードする方法を説明します。

デバイスから IoT ハブにテレメトリを送信する方法」のクイックスタートと 「IoT Hub で cloud-to-device メッセージを送信する方法」の記事には、IoT Hub の基本的な device-to-cloud メッセージと cloud-to-device メッセージの機能が示されています。 「IoT Hub を使用してメッセージ ルーティングを構成する」の記事では、device-to-cloud メッセージを Microsoft Azure BLOB ストレージに確実に格納する方法を示します。 ただし、一部のシナリオでは、デバイスが送信するデータを、IoT Hub が受け入れる比較的小さな device-to-cloud メッセージに簡単にはマップできません。 次に例を示します。

  • ビデオ
  • イメージを含む大きなファイル
  • 高頻度でサンプリングされる振動データ
  • 何らかの形式の前処理済みデータ

これらのファイルは通常、Azure Data FactoryHadoop スタックなどのツールを使ってクラウドでバッチ処理されます。 デバイスからファイルをアップロードする必要がある場合も、IoT Hub のセキュリティと信頼性を利用できます。 この記事では、その方法について説明します。

この記事の最後に、次の 2 つの .NET コンソール アプリを実行します。

  • FileUploadSample。 このデバイス アプリは、IoT Hub によって提供されている SAS URI を使用してストレージにファイルをアップロードします。 このサンプルは、前提条件でダウンロードした Azure IoT C# SDK リポジトリからのものです。

  • ReadFileUploadNotification。 このサービス アプリは、IoT ハブからのファイル アップロード通知を受信します。 このアプリは、ユーザーが作成します。

注意

IoT Hub は、Azure IoT device SDK を介して、多数のデバイス プラットフォームと言語 (C、Java、Python、JavaScript を含む) をサポートしています。 デバイスを Azure IoT Hub に接続する方法については、Azure IoT デベロッパー センターを参照してください。

重要

X.509 証明機関 (CA) 認証を使用するデバイスのファイル アップロード機能はパブリック プレビュー段階であり、プレビュー モードを有効にする必要があります。 これは、Azure デバイス プロビジョニング サービスで x.509 拇印認証または x.509 証明書の構成証明を使用するデバイスで一般提供されています。 IoT Hub での X.509 認証の詳細については、「サポートされている X.509 証明書」を参照してください。

前提条件

  • IoT Hub。 CLI または Azure portal を使って作成します。

  • 登録済みのデバイス。 Azure portal に登録してください。

  • この記事で実行するサンプル アプリケーションは、C# と .NET Core を使って記述されています。

    複数のプラットフォームに対応する .NET Core SDK を .NET からダウンロードします。

    開発マシンに現在インストールされている .NET Core SDK のバージョンを、次のコマンドを使って確認します。

    dotnet --version
    
  • ダウンロード サンプルから Azure IoT C# SDK をダウンロードし、ZIP アーカイブを展開します。

  • ポート 8883 は、ファイアウォールで開放されている必要があります。 この記事のサンプルでは、ポート 8883 を介して通信する MQTT プロトコルを使用しています。 このポートは、企業や教育用のネットワーク環境によってはブロックされている場合があります。 この問題の詳細と対処方法については、「IoT Hub への接続 (MQTT)」を参照してください。

IoT Hub への Azure Storage アカウントの関連付け

デバイスからファイルをアップロードするには、IoT ハブに関連付けられている Azure Storage アカウントと Azure Blob Storage コンテナーが必要です。 ストレージ アカウントとコンテナーを IoT ハブに関連付けると、デバイスから要求されたときに、その IoT ハブで SAS URI の要素を提供できます。 デバイスではその後、これらの要素を使用して SAS URI を構築でき、この URI を使用して Azure Storage との間で認証を行い、BLOB コンテナーにファイルをアップロードします。

Azure Storage アカウントを IoT ハブに関連付けるには:

  1. IoT ハブの左側のペインにある [Hub settings](ハブの設定) で、 [ファイルのアップロード] を選びます。

    ポータルから [ファイルのアップロード] 設定の選択を示すスクリーン キャプチャ。

  2. [ファイルのアップロード] ペインで、 [Azure Storage コンテナー] を選択します。 この記事の場合は、ストレージ アカウントと IoT Hub を同じリージョンに配置することをお勧めします。

    • 使おうとしているストレージ アカウントが既にある場合は、一覧からそれを選択します。

    • 新しいストレージ アカウントを作成するには、 [+ストレージ アカウント] を選択します。 ストレージ アカウントの名前を指定し、 [場所] が、お使いの IoT ハブと同じリージョンに設定されていることを確認し、 [OK] を選択します。 IoT ハブと同じリソース グループに新しいアカウントが作成されます。 デプロイが完了したら、一覧からそのストレージ アカウントを選択します。

    ストレージ アカウントを選択すると、 [コンテナー] ペインが開きます。

  3. [コンテナー] ペインで、BLOB コンテナーを選択します。

    • 使おうとしている BLOB コンテナーが既にある場合は、一覧からそれを選択し、 [選択] をクリックします。

    • 新しい BLOB コンテナーを作成するには、 [+ コンテナー] を選択します。 新しいコンテナーの名前を指定します。 この記事の目的上、他のフィールドはすべて既定のままにすることができます。 [作成] を選択します デプロイが完了したら、一覧からコンテナーを選択し、 [選択] をクリックします。

  4. [ファイルのアップロード] ペインに戻り、ファイル通知が [オン] に設定されていることを確認します。 他の設定はすべて既定値のままにすることができます。 [保存] を選択し、設定が完了するのを待ってから次のセクションに進みます。

    ポータルの [ファイルのアップロード] 設定の確認を示すスクリーン キャプチャ。

Azure Storage アカウントを作成する方法の詳細な手順については、「ストレージ アカウントを作成する」を参照してください。 ストレージ アカウントと BLOB コンテナーを IoT ハブに関連付ける方法の詳細な手順については、Azure portal を使用してファイルのアップロードを構成することに関するページを参照してください。

デバイス アプリからのファイルのアップロード

この記事では、事前にダウンロードした 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 Hub デバイス クライアントを作成した後、デバイスからファイルをアップロードするための標準的な 3 つの手順が実行されます。

  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 Storage にアップロードします。 このサンプルでは、SAS URI を使用して Azure Storage ブロック BLOB クライアントを作成し、ファイルをアップロードします。

    var blockBlobClient = new BlockBlobClient(uploadUri);
    await blockBlobClient.UploadAsync(fileStreamSource, new BlobUploadOptions());
    
  3. このコードは、アップロードが完了したことを IoT ハブに通知します。 これにより、アップロードに関連するリソース (SAS URI) を解放してもよいことが、IoT ハブに通知されます。 ファイルのアップロード通知が有効になっている場合、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 Hub と通信します。 このトランスポート プロトコルは、パラメーター t を使用することで変更できます。 この選択に関係なく、Azure BLOB クライアントでは、ファイルを Azure ストレージにアップロードするプロトコルとして、常に HTTPS が使用されます。

IoT ハブ接続文字列を取得する

この記事では、IoT ハブからファイル アップロード通知メッセージを受信するバックエンド サービスを作成しました。 ファイル アップロード通知メッセージを受信するサービスには、サービス接続のアクセス許可が必要となります。 既定では、どの IoT Hub も、このアクセス許可を付与する service という名前の共有アクセス ポリシーがある状態で作成されます。

サービス ポリシーの IoT Hub 接続文字列を取得するには、次の手順を実行します。

  1. Azure portal で、 [リソース グループ] を選択します。 ハブが配置されているリソース グループを選択し、リソースの一覧からハブを選択します。

  2. IoT ハブの左側のウィンドウで、 [共有アクセス ポリシー] を選択します。

  3. ポリシーの一覧から、サービス ポリシーを選択します。

  4. [プライマリ接続文字列] をコピーし、値を保存します。

Azure portal で IoT ハブから接続文字列を取得する方法を示すスクリーンショット。

IoT Hub の共有アクセス ポリシーとアクセス許可の詳細については、「アクセス制御とアクセス許可」を参照してください。

ファイル アップロードの通知の受信

このセクションでは、IoT ハブからファイル アップロードの通知メッセージを受信する C# コンソール アプリを作成します。

  1. コマンド ウィンドウを開いて、プロジェクトを作成するフォルダーに移動します。 ReadFileUploadNotifications という名前のフォルダーを作成し、そのフォルダーへのディレクトリを変更します。

    mkdir ReadFileUploadNotification
    cd ReadFileUploadNotification
    
  2. 次のコマンドを実行して、C# コンソール プロジェクトを作成します。 コマンドを実行すると、Program.cs ファイルと ReadFileUploadNotification.csproj ファイルがフォルダーに格納されます。

    dotnet new console --language c#
    
  3. 次のコマンドを実行して、Microsoft.Azure.Devices パッケージをプロジェクト ファイルに追加します。 このパッケージは、.Azure IoT .NET service 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 Storage にアップロードします。 新しいコマンド プロンプトを開き、フォルダーを Azure IoT C# SDK を解凍した下にある azure-iot-sdk-csharp\iothub\device\samples\getting started\FileUploadSample フォルダーに変更します。 次のコマンドを実行します。 2 つ目のコマンドにある {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.windows.net/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 portal のストレージ アカウントに移動します。

  2. ストレージ アカウントの左ペインで、 [コンテナー] を選択します。

  3. ファイルをアップロードしたコンテナーを選択します。

  4. デバイスにちなんだ名前のフォルダーを選択します。

  5. ファイルをアップロードした BLOB を選択します。 この記事では、TestPayload.txt という名前の BLOB です。

    アップロードされたファイルを Azure portal で選択しているスクリーンショット。

  6. 開いたページで BLOB のプロパティを表示します。 [ダウンロード] を選択 してファイルをダウンロードし、その内容をローカルで表示できます。

次の手順

この記事では、IoT Hub のファイル アップロード機能を使用して、デバイスからのファイルのアップロードを簡素化する方法を学習しました。 この機能をさらに詳しく知るには、以下の記事を参考にしてください。