cloud-to-device メッセージを送受信する
Azure IoT Hub は、ソリューション バックエンドから数百万台のデバイスへの cloud-to-device (C2D) メッセージを含む双方向通信を可能にするフル マネージド サービスです。
この記事では、Azure IoT SDK を使用して次の種類のアプリケーションをビルドする方法について説明します。
IoT Hub メッセージング キューから cloud-to-device メッセージを受信して処理するデバイス アプリケーション。
IoT Hub メッセージング キューを介して cloud-to-device メッセージを 1 つのデバイスに送信するバックエンド アプリケーション。
この記事は、この記事内から参照される実行可能な SDK サンプルを補完するためのものです。
Note
この記事で説明されている機能は、Standard レベルの IoT Hub でのみ使用できます。 Basic および Standard または Free レベルの IoT Hub の詳細については、ソリューションに適した IoT Hub のレベルの選択に関するページを参照してください。
概要
デバイス アプリケーションが cloud-to-device メッセージを受信するには、IoT Hub に接続し、受信メッセージを処理するメッセージ ハンドラーを設定する必要があります。 Azure IoT Hub デバイス SDK は、デバイスがサービスからのメッセージの受信と処理に使用できるクラスとメソッドを提供します。 この記事では、メッセージを受信するデバイス アプリケーションの、次のような主要な要素について説明します。
- デバイス クライアント オブジェクトを宣言する
- IoT Hub への接続
- IoT Hub メッセージ キューからメッセージを取得する
- メッセージを処理し、受信確認を IoT Hub に送り返す
- メッセージ受信再試行ポリシーを構成する
バックエンド アプリケーションが cloud-to-device メッセージを送信するには、IoT Hub に接続し、IoT Hub メッセージ キューを介してメッセージを送信する必要があります。 Azure IoT Hub サービス SDK は、アプリケーションがデバイスにメッセージを送信するために使用できるクラスとメソッドを提供します。 この記事では、デバイスにメッセージを送信するアプリケーションの次のような主な要素について説明します。
- サービス クライアント オブジェクトを宣言する
- IoT Hub への接続
- メッセージをビルドして送信する
- 配信フィードバックの受信
- メッセージ送信再試行ポリシーを構成する
メッセージ キューについて
cloud-to-device メッセージングを理解するには、IoT Hub デバイス メッセージ キューがどのように機能するかについて、いくつかの基礎を理解することが重要です。
ソリューション バックエンド アプリケーションから IoT デバイスに送信される cloud-to-device メッセージは、IoT Hub 経由でルーティングされます。 ソリューション バックエンド アプリケーションとターゲット デバイスの間には、直接のピアツーピア メッセージング通信はありません。 IoT Hub は受信メッセージをメッセージ キューに配置し、これらのメッセージをターゲット IoT デバイスでダウンロードする準備が整います。
少なくとも 1 回のメッセージ配信を保証するために、IoT Hub は cloud-to-device メッセージをデバイスごとのキューに保持します。 IoT Hub がキューからメッセージを削除する前に、デバイスはメッセージの完了を明示的に確認する必要があります。 このような方法で、接続とデバイスの障害に対する復元性が保証されます。
IoT Hub は、デバイス メッセージ キューにメッセージを配置すると、メッセージの状態を "エンキュー済み" に設定します。 デバイス スレッドがキューからメッセージを受け取ると、IoT Hub はメッセージの状態を "非表示" に設定してメッセージをロックします。 この状態により、デバイス上の他のスレッドが同じメッセージを処理できなくなります。 デバイス スレッドがメッセージの処理を正常に完了すると、IoT Hub に通知され、IoT Hub によってメッセージの状態が "完了" に設定されます。
メッセージを正常に受信して処理するデバイス アプリケーションは、メッセージを "完了" するように指示されます。 ただし、必要に応じてデバイスは次のこともできます。
- メッセージの "拒否"。この場合、IoT Hub によってメッセージの状態は配信不能に設定されます。 メッセージ キュー テレメトリ転送 (MQTT) プロトコル経由で接続するデバイスでは、cloud-to-device メッセージを拒否することはできません。
- メッセージの "破棄"。この場合、IoT Hub によってメッセージがキューに戻され、メッセージの状態が "エンキュー済" に設定されます。 MQTT プロトコル経由で接続するデバイスでは、cloud-to-device メッセージを破棄することはできません。
cloud-to-device メッセージのライフサイクルと、IoT Hub が cloud-to-device メッセージを処理する方法の詳細については、「IoT ハブから cloud-to-device メッセージを送信する」を参照してください。
デバイス アプリケーションを作成する
このセクションでは、クラウドからデバイスへのメッセージを受信する方法について説明します。
デバイス クライアント アプリケーションがメッセージの受信に使用できるオプションは 2 つあります。
- コールバック: デバイス アプリケーションは、メッセージが到着するとすぐに呼び出される非同期メッセージ ハンドラー メソッドを設定します。
- ポーリング: デバイス アプリケーションは、コード ループ (たとえば、
while
またはfor
ループ) を使用して新しい IoT Hub メッセージをチェックします。 ループは継続的に実行され、メッセージがチェックされます。
必要なデバイス NuGet パッケージ
C# で記述されたデバイス クライアント アプリケーションには、Microsoft.Azure.Devices.Client NuGet パッケージが必要です。
次の using
ステートメントを追加して、デバイス ライブラリを使用します。
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
デバイスを IoT Hub に接続する
デバイス アプリは、以下の方法を使用して IoT Hub で認証することができます。
- 共有アクセス キー
- X.509 証明書
重要
この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。
共有アクセス キーを使用して認証する
DeviceClient クラスは、デバイスでメッセージを受信するために必要なすべてのメソッドを公開します。
接続パラメーターを指定する
CreateFromConnectionString メソッドを使用して、IoT Hub のプライマリ接続文字列とデバイス ID を DeviceClient
に指定します。 必要な IoT Hub プライマリ接続文字列に加えて、CreateFromConnectionString
メソッドをオーバーロードして、次の "省略可能な" パラメーターを含めることができます。
transportType
- トランスポート プロトコル: HTTP バージョン 1、AMQP、または MQTT のバリエーション。AMQP
は既定値です。 使用可能なすべての値を表示するには、「TransportType 列挙型」を参照してください。transportSettings
-DeviceClient
とModuleClient
のさまざまなトランスポート固有の設定を定義するために使用されるインターフェイス。 詳細については、「ITransportSettings インターフェイス」を参照してください。ClientOptions
- 初期化中にデバイスまたはモジュール クライアント インスタンスの構成を許可するオプション。
この例では、Mqtt
トランスポート プロトコルを使用してデバイスに接続します。
static string DeviceConnectionString = "{IoT hub device connection string}";
static deviceClient = null;
deviceClient = DeviceClient.CreateFromConnectionString(DeviceConnectionString,
TransportType.Mqtt);
X.509 証明書を使用して認証する
X.509 証明書を使用してデバイスを IoT Hub に接続するには:
DeviceAuthenticationWithX509Certificate を使用して、デバイスと証明書の情報を含むオブジェクトを作成します。
DeviceAuthenticationWithX509Certificate
は、DeviceClient.Create
に対する 2 番目のパラメーターとして渡されます (手順 2)。DeviceClient.Create を使用することで、X.509 証明書を使用してデバイスを IoT Hub に接続します。
この例では、デバイスと証明書の情報は、DeviceClient.Create
に渡される auth
DeviceAuthenticationWithX509Certificate
オブジェクトに設定されます。
この例では、分かりやすさのために、証明書入力パラメーターの値をローカル変数として表しています。 運用システムでは、機密性の高い入力パラメーターは環境変数やその他のより安全な保存場所に保存してください。 たとえば、Environment.GetEnvironmentVariable("HOSTNAME")
を使用してホスト名環境変数を読み取ります。
RootCertPath = "~/certificates/certs/sensor-thl-001-device.cert.pem";
Intermediate1CertPath = "~/certificates/certs/sensor-thl-001-device.intermediate1.cert.pem";
Intermediate2CertPath = "~/certificates/certs/sensor-thl-001-device.intermediate2.cert.pem";
DevicePfxPath = "~/certificates/certs/sensor-thl-001-device.cert.pfx";
DevicePfxPassword = "1234";
DeviceName = "MyDevice";
HostName = "xxxxx.azure-devices.net";
var chainCerts = new X509Certificate2Collection();
chainCerts.Add(new X509Certificate2(RootCertPath));
chainCerts.Add(new X509Certificate2(Intermediate1CertPath));
chainCerts.Add(new X509Certificate2(Intermediate2CertPath));
using var deviceCert = new X509Certificate2(DevicePfxPath, DevicePfxPassword);
using var auth = new DeviceAuthenticationWithX509Certificate(DeviceName, deviceCert, chainCerts);
using var deviceClient = DeviceClient.Create(
HostName,
auth,
TransportType.Amqp);
証明書認証の詳細については、以下を参照してください。
コード サンプル
デバイスの X.509 証明書認証の実際に動作するサンプルについては、以下を参照してください。
- X.509 証明書を使用して接続する
- DeviceClientX509AuthenticationE2ETests
- ガイド付きプロジェクト - IoT Hub Device Provisioning Service を使用して IoT デバイスを安全かつ大規模にプロビジョニングする
Callback
デバイス アプリケーションでコールバック cloud-to-device メッセージを受信するには、アプリケーションが IoT Hub に接続し、受信メッセージを処理するためのコールバック リスナーを設定する必要があります。 デバイスへの受信メッセージは、IoT Hub メッセージ キューから受信されます。
コールバックを使用して、デバイス アプリケーションは、SetReceiveMessageHandlerAsync を使用してメッセージ ハンドラー メソッドを設定します。 メッセージ ハンドラーが呼び出され、メッセージが受信されます。 メッセージを受信するコールバック メソッドを作成すると、受信したメッセージを継続的にポーリングする必要がなくなります。
コールバックは、次のプロトコルでのみ使用可能になります。
Mqtt
Mqtt_WebSocket_Only
Mqtt_Tcp_Only
Amqp
Amqp_WebSocket_Only
Amqp_Tcp_only
Http1
プロトコル オプションはコールバックをサポートしていません。これは、SDK メソッドが受信したメッセージをポーリングする必要があるためで、これによりコールバックの原則が無効になります。
この例で、SetReceiveMessageHandlerAsync
は、メッセージを受信するたびに呼び出される OnC2dMessageReceivedAsync
という名前のコールバック ハンドラー メソッドを設定します。
// Subscribe to receive C2D messages through a callback (which isn't supported over HTTP).
await deviceClient.SetReceiveMessageHandlerAsync(OnC2dMessageReceivedAsync, deviceClient);
Console.WriteLine($"\n{DateTime.Now}> Subscribed to receive C2D messages over callback.");
ポーリング
ポーリングでは、ReceiveAsync を使用してメッセージをチェックします。
ReceiveAsync
の呼び出しには、次の形式を使用できます。
ReceiveAsync()
- メッセージの既定のタイムアウト期間を待機してから続行します。ReceiveAsync (Timespan)
- 特定のタイムアウトを使用して、デバイス キューからメッセージを受信します。ReceiveAsync (CancellationToken)
- キャンセル トークンを使用して、デバイス キューからメッセージを受信します。 キャンセル トークンを使用する場合、既定のタイムアウト期間は使用されません。
MQTT または AMQP の代わりに HTTP 1 のトランスポート型を使用すると、ReceiveAsync
メソッドはすぐに返されます。 HTTP 1 を使用する cloud-to-device メッセージに関してサポートされているパターンは、メッセージを低頻度 (最小 25 分の間隔) でチェックする、断続的に接続されるデバイスです。 HTTP 1 受信の発行が多くなれば、IoT Hub で要求が調整されます。 MQTT、AMQP、および HTTP 1 のサポートの相違点の詳細については、「cloud-to-device 通信に関するガイダンス」と「通信プロトコルの選択」を参照してください。
CompleteAsync メソッド
デバイスがメッセージを受信すると、デバイス アプリケーションは CompleteAsync メソッドを呼び出して、メッセージが正常に処理され、メッセージを IoT Hub デバイス キューから安全に削除できることを IoT Hub に通知します。 デバイスは、使用しているトランスポート プロトコルに関係なく、処理が正常に完了したときに、このメソッドを呼び出す必要があります。
メッセージの破棄、拒否、またはタイムアウト
MQTT プロトコルではできませんが、AMQP および HTTP バージョン 1 プロトコルでは、デバイスは次のこともできます。
- AbandonAsync を呼び出してメッセージを破棄します。 この場合、IoT Hub は将来の使用に備えてメッセージをデバイスのキュー内に保持します。
- RejectAsync を呼び出してメッセージを拒否します。 これにより、メッセージがデバイス キューから完全に削除されます。
デバイスがメッセージを完了、破棄、または拒否することを妨げる問題が発生した場合、IoT Hub は一定のタイムアウト期間が経過した後で、メッセージの配信をキューに入れます。 このような理由から、同じメッセージを複数回受信した場合に生成される結果が毎回同じになるように、デバイス アプリ内のメッセージ処理ロジックをべき等にする必要があります。
cloud-to-device メッセージのライフサイクルと、IoT Hub が cloud-to-device メッセージを処理する方法の詳細については、「IoT ハブから cloud-to-device メッセージを送信する」を参照してください。
ポーリング ループ
ポーリングを使用するアプリケーションでは、ReceiveAsync
メソッドを繰り返し呼び出すコード ループを使用して、停止するまで新しいメッセージを確認します。
タイムアウト値または既定のタイムアウトで ReceiveAsync
を使用する場合は、ループ内の ReceiveAsync
の呼び出しごとに、指定されたタイムアウト期間を待機します。 ReceiveAsync
がタイムアウトすると、null
値が返され、ループが続行されます。
メッセージを受信すると、Task オブジェクトが ReceiveAsync
によって返され、CompleteAsync に渡されます。 CompleteAsync
の呼び出しは、Task
パラメーターに基づいて、指定したメッセージをメッセージ キューから削除するよう IoT Hub に通知します。
この例では、メッセージを受信するか、ポーリング ループが停止するまで、ループが ReceiveAsync
を呼び出します。
static bool stopPolling = false;
while (!stopPolling)
{
// Check for a message. Wait for the default DeviceClient timeout period.
using Message receivedMessage = await _deviceClient.ReceiveAsync();
// Continue if no message was received
if (receivedMessage == null)
{
continue;
}
else // A message was received
{
// Print the message received
Console.WriteLine($"{DateTime.Now}> Polling using ReceiveAsync() - received message with Id={receivedMessage.MessageId}");
PrintMessage(receivedMessage);
// Notify IoT Hub that the message was received. IoT Hub will delete the message from the message queue.
await _deviceClient.CompleteAsync(receivedMessage);
Console.WriteLine($"{DateTime.Now}> Completed C2D message with Id={receivedMessage.MessageId}.");
}
// Check to see if polling loop should end
stopPolling = ShouldPollingstop ();
}
メッセージの受信再試行ポリシー
デバイス クライアント メッセージ再試行ポリシーは、DeviceClient.SetRetryPolicy を使用して定義できます。
メッセージ再試行タイムアウトは、DeviceClient.OperationTimeoutInMilliseconds プロパティに格納されます。
SDK 受信メッセージのサンプル
.NET/C# SDK には、このセクションで説明する受信メッセージ メソッドを含む Message Receive サンプルが含まれています。
バックエンド アプリケーションを作成する
このセクションでは、Azure IoT SDK for .NET の ServiceClient クラスを使用して、ソリューション バックエンド アプリケーションから IoT デバイスにメッセージを送信するための重要なコードについて説明します。 前に説明したように、ソリューション バックエンド アプリケーションは IoT Hub に接続し、メッセージは宛先デバイスでエンコードされて IoT Hub に送信されます。 IoT Hub は受信メッセージをメッセージ キューに格納し、メッセージは IoT Hub メッセージ キューからターゲット デバイスに配信されます。
ソリューション バックエンド アプリケーションは、メッセージ キューを介したデバイス配信を宛先とする、IoT Hub に送信されたメッセージの配信フィードバックを要求および受信することもできます。
サービス NuGet パッケージを追加する
バックエンド サービス アプリケーションには、Microsoft.Azure.Devices NuGet パッケージが必要です。
IoT Hub に接続する
次の方法を使用して、バックエンド サービスを IoT Hub に接続できます。
- 共有アクセス ポリシー
- Microsoft Entra
重要
この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>
共有アクセス ポリシーを使用して接続する
接続文字列を指定する
CreateFromConnectionString を使用して、バックエンド アプリケーションをデバイスに接続します。 必要な IoT Hub プライマリ接続文字列に加えて、CreateFromConnectionString
メソッドをオーバーロードして、次の "省略可能な" パラメーターを含めることができます。
transportType
-Amqp
またはAmqp_WebSocket_Only
。transportSettings
- サービス クライアントの AMQP および HTTP プロキシ設定。ServiceClientOptions
- 初期化中にサービス クライアント インスタンスの構成を許可するオプション。 詳細については、ServiceClientOptions の説明を参照してください。
この例では、IoT Hub 接続文字列と既定の Amqp
トランスポートを使用して、ServiceClient
オブジェクトを作成します。
static string connectionString = "{your IoT hub connection string}";
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
Microsoft Entra を使用して接続する
Microsoft Entra を使用するバックエンド アプリは、IoT Hub に接続する前に、認証に成功してセキュリティ トークンの資格情報を取得する必要があります。 このトークンは、IoT Hub 接続メソッドに渡されます。 IoT Hub 用の Microsoft Entra の設定と使用に関する一般的な情報については、「Microsoft Entra ID を使用した IoT Hub へのアクセス制御」を参照してください。
Microsoft Entra アプリを構成する
優先する認証資格情報用に構成された Microsoft Entra アプリを設定する必要があります。 このアプリには、バックエンド アプリケーションで認証に使用されるクライアント シークレットなどのパラメーターが含まれています。 使用可能なアプリ認証構成は次のとおりです。
- クライアント シークレット
- [証明書]
- フェデレーション ID 資格情報
Microsoft Entra アプリでは、実行される操作に応じて、特定のロールのアクセス許可が必要になる場合があります。 たとえば、IoT Hub デバイスとモジュール ツインへの読み取りと書き込みアクセスを有効にするには、IoT Hub ツイン共同作成者が必要です。 詳細については、「Azure RBAC ロールの割り当てを使用して IoT Hub へのアクセスを管理する」を参照してください。
Microsoft Entra アプリの設定の詳細については、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。
DefaultAzureCredential を使用して認証する
Microsoft Entra を使用してバックエンド アプリケーションを認証する最も簡単な方法は、DefaultAzureCredential を使用することですが、特定の TokenCredential
や削減された ChainedTokenCredential
など、運用環境では別の方法を使用することをお勧めします。 わかりやすくするために、このセクションでは、 DefaultAzureCredential
とクライアント シークレットを使用した認証について説明します。 DefaultAzureCredential
を使用する長所と短所の詳細については、「DefaultAzureCredential の使用ガイダンス」を参照してください。
DefaultAzureCredential
では、さまざまな認証メカニズムがサポートされ、実行されている環境に基づいて適切な資格情報の種類が決まります。 有効な資格情報が見つかるまで、複数の種類の資格情報の使用を順番に試みます。
Microsoft Entra には、次の NuGet パッケージと、対応する using
ステートメントが必要です。
- Azure.Core
- Azure.Identity
using Azure.Core;
using Azure.Identity;
この例では、Microsoft Entra アプリ登録のクライアント シークレット、クライアント ID、テナント ID が環境変数に追加されます。 これらの環境変数は、アプリケーションを認証するために DefaultAzureCredential
で使用されます。 Microsoft Entra 認証が成功した結果、セキュリティ トークン資格情報が IoT Hub 接続メソッドに渡されます。
string clientSecretValue = "xxxxxxxxxxxxxxx";
string clientID = "xxxxxxxxxxxxxx";
string tenantID = "xxxxxxxxxxxxx";
Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", clientSecretValue);
Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientID);
Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantID);
TokenCredential tokenCredential = new DefaultAzureCredential();
結果として得られる TokenCredential は、Microsoft Entra 資格情報を受け入れる SDK クライアントの IoT Hub メソッドに接続するために渡すことができます。
次の例では、ServiceClient 接続オブジェクトを作成するために、TokenCredential
が ServiceClient.Create
に渡されます。
string hostname = "xxxxxxxxxx.azure-devices.net";
using var serviceClient = ServiceClient.Create(hostname, tokenCredential, TransportType.Amqp);
次の例では、RegistryManager オブジェクトを作成するために、TokenCredential
が RegistryManager.Create
に渡されます。
string hostname = "xxxxxxxxxx.azure-devices.net";
registryManager = RegistryManager.Create(hostname, tokenCredential);
コード サンプル
Microsoft Entra サービス認証の作業サンプルについては、ロール ベースの認証のサンプルのページを参照してください。
非同期の cloud-to-device メッセージを送信する
sendAsync を使用して、クラウド (IoT Hub) 経由でアプリケーションからデバイスに非同期メッセージを送信します。 呼び出しは AMQP プロトコルを使用して行われます。
sendAsync
は次のパラメーターを使用します。
deviceID
- ターゲット デバイスの文字列識別子。message
- cloud-to-device メッセージ。 メッセージは Message 型であり、適宜書式設定できます。timeout
- "省略可能な" タイムアウト値。 既定値は、指定しない場合は 1 分です。
この例では、10 秒のタイムアウト値を持つテスト メッセージをターゲット デバイスに送信します。
string targetDevice = "Device-1";
static readonly TimeSpan operationTimeout = TimeSpan.FromSeconds(10);
var commandMessage = new
Message(Encoding.ASCII.GetBytes("Cloud to device message."));
await serviceClient.SendAsync(targetDevice, commandMessage, operationTimeout);
配信フィードバックの受信
送信プログラムは、各 cloud-to-device メッセージに対して IoT Hub からの配信 (または有効期限) 確認を要求できます。 このオプションを使用すると、送信プログラムで通知、再試行、または補正ロジックを使用できます。 メッセージのフィードバック操作とプロパティの詳細については、「メッセージのフィードバック」を参照してください。
メッセージ配信フィードバックを受け取る方法:
feedbackReceiver
オブジェクトを作成するAck
パラメーターを使用してメッセージを送信する- フィードバックの受信を待機する
feedbackReceiver オブジェクトを作成する
GetFeedbackReceiver を呼び出して、FeedbackReceiver オブジェクトを作成します。 FeedbackReceiver
には、フィードバック受信操作を実行するためにサービスが使用できるメソッドが含まれています。
var feedbackReceiver = serviceClient.GetFeedbackReceiver();
Ack パラメーターを使用してメッセージを送信する
配信フィードバックを受信するには、各メッセージに配信確認の Ack プロパティの値を含める必要があります。 Ack
プロパティには、次の値のいずれかを指定することができます。
none (既定値): フィードバック メッセージは生成されません。
Positive
: メッセージが完了した場合は、フィードバック メッセージを受信します。Negative
: デバイスが完了せずにメッセージの有効期限が切れた (または最大配信数に達した) 場合は、フィードバック メッセージを受信します。Full
:Positive
とNegative
の両方の結果に関するフィードバック。
この例では、Ack
プロパティが Full
に設定され、1 つのメッセージに対して肯定的または否定的なメッセージ配信フィードバックの両方が要求されます。
var commandMessage = new
Message(Encoding.ASCII.GetBytes("Cloud to device message."));
commandMessage.Ack = DeliveryAcknowledgement.Full;
await serviceClient.SendAsync(targetDevice, commandMessage);
フィードバックの受信を待機する
CancellationToken
を定義します。 次に、ループ内で ReceiveAsync を繰り返し呼び出し、配信フィードバック メッセージを確認します。 ReceiveAsync
の各呼び出しは、ServiceClient
オブジェクトに対して定義されたタイムアウト期間待機します。
ReceiveAsync
タイムアウトがメッセージを受信せず期限切れになった場合、ReceiveAsync
はnull
を返し、ループは続行されます。- フィードバック メッセージを受信すると、
ReceiveAsync
によって Task オブジェクトが返されます。これは、キャンセル トークンと共に CompleteAsync に渡す必要があります。CompleteAsync
を呼び出すと、Task
パラメーターに基づいて、指定した送信済みメッセージがメッセージ キューから削除されます。 - 必要に応じて、受信コードは AbandonAsync を呼び出して送信メッセージをキューに戻すことができます。
var feedbackReceiver = serviceClient.GetFeedbackReceiver();
// Define the cancellation token.
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
// Call ReceiveAsync, passing the token. Wait for the timout period.
var feedbackBatch = await feedbackReceiver.ReceiveAsync(token);
if (feedbackBatch == null) continue;
この例では、次の手順を含むメソッドを示します。
private async static void ReceiveFeedbackAsync()
{
var feedbackReceiver = serviceClient.GetFeedbackReceiver();
Console.WriteLine("\nReceiving c2d feedback from service");
while (true)
{
// Check for messages, wait for the timeout period.
var feedbackBatch = await feedbackReceiver.ReceiveAsync();
// Continue the loop if null is received after a timeout.
if (feedbackBatch == null) continue;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received feedback: {0}",
string.Join(", ", feedbackBatch.Records.Select(f => f.StatusCode)));
Console.ResetColor();
await feedbackReceiver.CompleteAsync(feedbackBatch);
}
}
このフィードバック受信パターンは、デバイス アプリケーションで cloud-to-device メッセージを受信するために使用されるパターンに似ています。
サービス クライアントの再接続
例外が発生すると、サービス クライアントはその情報を呼び出し元のアプリケーションに中継します。 その時点で、例外の詳細を調べて、必要なアクションを実行することをお勧めします。
次に例を示します。
- ネットワーク例外の場合は、操作を再試行できます。
- セキュリティ例外 (未承認の例外) の場合は、資格情報を調べて、最新の状態であることを確認します。
- 調整/クォータ超過の例外の場合は、要求の送信頻度を監視および変更、またはそのいずれかを実行するか、ハブ インスタンス スケール ユニットを更新します。 詳細については、「IoT Hub のクォータと調整」を参照してください。
メッセージ送信再試行ポリシー
ServiceClient
メッセージ再試行ポリシーは、ServiceClient.SetRetryPolicy を使用して定義できます。
SDK 送信メッセージのサンプル
.NET/C# SDK には、このセクションで説明するメッセージ送信メソッドを含むサービス クライアント サンプルが含まれています。
デバイス アプリケーションを作成する
このセクションでは、Azure IoT SDK for Java から DeviceClient クラスを使用して、cloud-to-device メッセージを受信する方法について説明します。
Java ベースのデバイス アプリケーションが cloud-to-device メッセージを受信するには、IoT Hub に接続してから、IoT Hub からの受信メッセージを処理するためのコールバック リスナーとメッセージ ハンドラーを設定する必要があります。
Azure IoT Java SDK ライブラリをインポートする
この記事で参照されているコードでは、次の SDK ライブラリを使用します。
import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.exceptions.IotHubClientException;
import com.microsoft.azure.sdk.iot.device.transport.IotHubConnectionStatus;
デバイスを IoT Hub に接続する
デバイス アプリは、以下の方法を使用して IoT Hub で認証することができます。
- 共有アクセス キー
- X.509 証明書
重要
この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。
共有アクセス キーを使用して認証する
DeviceClient オブジェクトのインスタンス化には、次のパラメーターが必要です。
- connString - IoT デバイス接続文字列。 接続文字列は、";" で区切られたキーと値のペアのセットであり、キーと値は "=" で区切られています。 次のキーの値が含まれている必要があります:
HostName, DeviceId, and SharedAccessKey
。 - トランスポート プロトコル -
DeviceClient
接続では、次の IoTHubClientProtocol トランスポート プロトコルのいずれかを使用できます。AMQP
は最も汎用性が高く、メッセージを頻繁にチェックでき、メッセージの拒否と取り消しができます。 MQTT では、メッセージの拒否または破棄のメソッドはサポートされていません。AMQPS
AMQPS_WS
HTTPS
MQTT
MQTT_WS
次に例を示します。
static string connectionString = "{IOT hub device connection string}";
static protocol = IotHubClientProtocol.AMQPS;
DeviceClient client = new DeviceClient(connectionString, protocol);
X.509 証明書を使用して認証する
X.509 証明書を使用してデバイスを IoT Hub に接続するには:
- buildSSLContext を使用して SSLContext オブジェクトをビルドします。
SSLContext
情報を ClientOptions オブジェクトに追加します。ClientOptions
情報を使用して DeviceClient を呼び出して、デバイスから IoT Hub への接続を作成します。
この例では、分かりやすさのために、証明書入力パラメーターの値をローカル変数として表しています。 運用システムでは、機密性の高い入力パラメーターは環境変数やその他のより安全な保存場所に保存してください。 たとえば、Environment.GetEnvironmentVariable("PUBLICKEY")
を使用して公開キー証明書文字列の環境変数を読み取ります。
private static final String publicKeyCertificateString =
"-----BEGIN CERTIFICATE-----\n" +
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
"-----END CERTIFICATE-----\n";
//PEM encoded representation of the private key
private static final String privateKeyString =
"-----BEGIN EC PRIVATE KEY-----\n" +
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
"-----END EC PRIVATE KEY-----\n";
SSLContext sslContext = SSLContextBuilder.buildSSLContext(publicKeyCertificateString, privateKeyString);
ClientOptions clientOptions = ClientOptions.builder().sslContext(sslContext).build();
DeviceClient client = new DeviceClient(connString, protocol, clientOptions);
証明書認証の詳細については、以下を参照してください。
コード サンプル
デバイスの X.509 証明書認証の実際に動作するサンプルについては、以下を参照してください。
メッセージ コールバック メソッドを設定する
setMessageCallback メソッドを使用して、IoT Hub からメッセージを受信したときに通知されるメッセージ ハンドラー メソッドを定義します。
setMessageCallback
には、次のパラメーターが含まれています。
callback
- コールバック メソッド名。null
の可能性があります。context
-object
型の "省略可能な" コンテキスト。 指定されていない場合は、null
を使用します。
この例では、コンテキスト パラメーターのない MessageCallback
という名前の callback
メソッドが setMessageCallback
に渡されます。
client.setMessageCallback(new MessageCallback(), null);
メッセージ コールバック ハンドラーを作成する
コールバック メッセージ ハンドラーは、IoT Hub メッセージ キューから渡された受信メッセージを受信して処理します。
この例では、メッセージ ハンドラーは受信メッセージを処理し、IotHubMessageResult.COMPLETE を返します。 戻り値 IotHubMessageResult.COMPLETE
は、メッセージが正常に処理されたことと、メッセージをデバイスのキューから安全に削除できることを IoT Hub に通知します。 デバイスは、処理が正常に完了したときに IotHubMessageResult.COMPLETE
を返し、使用しているプロトコルに関係なく、メッセージ キューからメッセージを削除する必要があることを IoT Hub に通知する必要があります。
protected static class MessageCallback implements com.microsoft.azure.sdk.iot.device.MessageCallback
{
public IotHubMessageResult onCloudToDeviceMessageReceived(Message msg, Object context)
{
System.out.println(
"Received message with content: " + new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET));
// Notify IoT Hub that the message
return IotHubMessageResult.COMPLETE;
}
}
メッセージの破棄と拒否のオプション
デバイスへの膨大な数の受信メッセージを正常に受信し、結果として IotHubMessageResult.COMPLETE
になる必要がありますが、メッセージを破棄または拒否することが必要な場合があります。
- MQTT ではなく、AMQP と HTTPS では、アプリケーションで次のことができます。
- メッセージの
IotHubMessageResult.ABANDON
。 IoT ハブは、これをキューに再登録し、後でもう一度送信します。 - メッセージの
IotHubMessageResult.REJECT
。 IoT ハブはメッセージをキューに再登録せず、メッセージ キューからメッセージを完全に削除します。
- メッセージの
MQTT
またはMQTT_WS
を使用しているクライアントは、メッセージをABANDON
またはREJECT
できません。
デバイスがメッセージを完了、破棄、または拒否することを妨げる問題が発生した場合、IoT Hub は一定のタイムアウト期間が経過した後で、メッセージの配信をキューに入れます。 このような理由から、同じメッセージを複数回受信した場合に生成される結果が毎回同じになるように、デバイス アプリ内のメッセージ処理ロジックをべき等にする必要があります。
cloud-to-device メッセージのライフサイクルと、IoT Hub が cloud-to-device メッセージを処理する方法の詳細については、「IoT ハブから cloud-to-device メッセージを送信する」を参照してください。
注意
トランスポートとして AMQP の代わりに HTTPS を使用した場合、DeviceClient インスタンスが IoT Hub からのメッセージをチェックする頻度は低くなります (最小 25 分の間隔)。 MQTT、AMQP、および HTTPS のサポートの相違点の詳細については、「cloud-to-device 通信に関するガイダンス」と「通信プロトコルの選択」を参照してください。
メッセージ状態コールバック メソッドを作成する
アプリケーションでは、registerConnectionStatusChangeCallback を使用して、デバイスの接続状態が変更されたときに実行されるコールバック メソッドを登録できます。 これにより、アプリケーションは切断されたメッセージ接続を検出し、再接続を試みることができます。
この例では、IotHubConnectionStatusChangeCallbackLogger
は接続状態変更コールバック メソッドとして登録されます。
client.registerConnectionStatusChangeCallback(new IotHubConnectionStatusChangeCallbackLogger(), new Object());
コールバックが発生し、ConnectionStatusChangeContext
オブジェクトが渡されます。
connectionStatusChangeContext.getNewStatus()
を呼び出して、現在の接続状態を取得します。
IotHubConnectionStatus status = connectionStatusChangeContext.getNewStatus();
返される接続状態は、次のいずれかの値になる可能性があります。
IotHubConnectionStatus.DISCONNECTED
IotHubConnectionStatus.DISCONNECTED_RETRYING
IotHubConnectionStatus.CONNECTED
connectionStatusChangeContext.getNewStatusReason()
を呼び出して、接続状態の変更の理由を取得します。
IotHubConnectionStatusChangeReason statusChangeReason = connectionStatusChangeContext.getNewStatusReason();
connectionStatusChangeContext.getCause()
を呼び出して、接続状態の変更の理由を確認します。 利用できる情報がない場合、getCause()
は null
を返す可能性があります。
Throwable throwable = connectionStatusChangeContext.getCause();
if (throwable != null)
throwable.printStackTrace();
状態変更コールバック メソッドの接続状態変更の状態、デバイスの状態が変更された理由、およびコンテキストを抽出する方法を示す完全なサンプルについては、この記事の「SDK 受信メッセージのサンプル」セクションに記載されている HandleMessages サンプルを参照してください。
デバイスと IoT Hub の間の接続を開く
open を使用して、デバイスと IoT Hub の間に接続を作成します。 これで、デバイスは IoT Hub との間でメッセージを非同期的に送受信できるようになります。 クライアントが既に開いている場合、メソッドは何も行いません。
client.open(true);
SDK 受信メッセージのサンプル
HandleMessages: Microsoft Azure IoT SDK for Java に含まれているサンプル デバイス アプリ。これは、IoT ハブに接続し、cloud-to-device メッセージを受信します。
バックエンド アプリケーションを作成する
このセクションでは、Azure IoT SDK for Java から ServiceClient クラスを使用して、cloud-to-device メッセージを送信する方法について説明します。 ソリューション バックエンド アプリケーションが IoT Hub に接続すると、メッセージは宛先デバイスでエンコードされて IoT Hub に送信されます。 IoT Hub は受信メッセージをメッセージ キューに格納し、メッセージは IoT Hub メッセージ キューからターゲット デバイスに配信されます。
ソリューション バックエンド アプリケーションは、メッセージ キューを介したデバイス配信を宛先とする、IoT Hub に送信されたメッセージの配信フィードバックを要求および受信することもできます。
依存関係ステートメントを追加する
依存関係を追加することにより、アプリケーションの iothub-java-service-client パッケージを使用して、IoT ハブ サービスと通信できます。
<dependency>
<groupId>com.microsoft.azure.sdk.iot</groupId>
<artifactId>iot-service-client</artifactId>
<version>1.7.23</version>
</dependency>
import ステートメントを追加する
次の import ステートメントを追加して、Azure IoT Java SDK と例外ハンドラーを使用します。
import com.microsoft.azure.sdk.iot.service.*;
import java.io.IOException;
import java.net.URISyntaxException;
IoT ハブに接続します
次の方法を使用して、バックエンド サービスを IoT Hub に接続できます。
- 共有アクセス ポリシー
- Microsoft Entra
重要
この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>
共有アクセス ポリシーを使用して接続する
接続プロトコルを定義する
IotHubServiceClientProtocol を使用して、サービス クライアントが IoT Hub と通信するために使用するアプリケーション層プロトコルを定義します。
IotHubServiceClientProtocol
は、AMQPS
または AMQPS_WS
列挙型のみを受け入れます。
IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
ServiceClient オブジェクトを作成する
IoT Hub 接続文字列とプロトコルを指定して、ServiceClient オブジェクトを作成します。
String connectionString = "{yourhubconnectionstring}";
ServiceClient serviceClient (connectionString, protocol);
アプリケーションと IoT Hub の間の接続を開く
AMQP 送信側接続を開きます。 このメソッドは、アプリケーションと IoT Hub の間の接続を作成します。
serviceClient.open();
Microsoft Entra を使用して接続する
Microsoft Entra を使用するバックエンド アプリは、IoT Hub に接続する前に、認証に成功してセキュリティ トークンの資格情報を取得する必要があります。 このトークンは、IoT Hub 接続メソッドに渡されます。 IoT Hub 用の Microsoft Entra の設定と使用に関する一般的な情報については、「Microsoft Entra ID を使用した IoT Hub へのアクセス制御」を参照してください。
Java SDK 認証の概要については、「Java と Azure ID を使用した Azure 認証」を参照してください。
わかりやすくするために、このセクションでは、クライアント シークレットを使用した認証について説明します。
Microsoft Entra アプリを構成する
優先する認証資格情報用に構成された Microsoft Entra アプリを設定する必要があります。 このアプリには、バックエンド アプリケーションで認証に使用されるクライアント シークレットなどのパラメーターが含まれています。 使用可能なアプリ認証構成は次のとおりです。
- クライアント シークレット
- [証明書]
- フェデレーション ID 資格情報
Microsoft Entra アプリでは、実行される操作に応じて、特定のロールのアクセス許可が必要になる場合があります。 たとえば、IoT Hub デバイスとモジュール ツインへの読み取りと書き込みアクセスを有効にするには、IoT Hub ツイン共同作成者が必要です。 詳細については、「Azure RBAC ロールの割り当てを使用して IoT Hub へのアクセスを管理する」を参照してください。
Microsoft Entra アプリの設定の詳細については、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。
DefaultAzureCredential を使用して認証する
Microsoft Entra を使用してバックエンド アプリケーションを認証する最も簡単な方法は、DefaultAzureCredential を使用することですが、特定の TokenCredential
や削減された ChainedTokenCredential
など、運用環境では別の方法を使用することをお勧めします。
DefaultAzureCredential
を使用する長所と短所の詳細については、「Java 用 Azure ID クライアント ライブラリの資格情報チェーン」を参照してください。
DefaultAzureCredential では、さまざまな認証メカニズムがサポートされ、実行されている環境に基づいて適切な資格情報の種類が決まります。 有効な資格情報が見つかるまで、複数の種類の資格情報の使用を順番に試みます。
Microsoft Entra アプリの資格情報は、DefaultAzureCredentialBuilder を使用して認証できます。 クライアント シークレット tenantID、clientID、クライアント シークレットの値などの接続パラメーターを環境変数として保存します。 TokenCredential
が作成されたら、それを 'credential' パラメーターとして ServiceClient またはその他のビルダーに渡します。
この例では、DefaultAzureCredentialBuilder
は、DefaultAzureCredential で説明されている一覧から接続の認証を試みます。 Microsoft Entra 認証が成功した結果として、セキュリティ トークン資格情報が ServiceClient などのコンストラクターに渡されます。
TokenCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build();
ClientSecretCredentialBuilder を使用して認証する
クライアント シークレット情報を使用して資格情報を作成するには、ClientSecretCredentialBuilder を使用できます。 成功した場合、このメソッドは ServiceClient またはその他のビルダーに 'credential' パラメーターとして渡すことができる TokenCredential を返します。
この例では、Microsoft Entra アプリ登録のクライアント シークレット、クライアント ID、テナント ID の値が環境変数に追加されました。 これらの環境変数は、資格情報を構築するために ClientSecretCredentialBuilder
によって使用されます。
string clientSecretValue = System.getenv("AZURE_CLIENT_SECRET");
string clientID = System.getenv("AZURE_CLIENT_ID");
string tenantID = System.getenv("AZURE_TENANT_ID");
TokenCredential credential =
new ClientSecretCredentialBuilder()
.tenantId(tenantID)
.clientId(clientID)
.clientSecret(clientSecretValue)
.build();
その他の認証クラス
Java SDK には、Microsoft Entra でバックエンド アプリを認証する次のクラスも含まれています。
- AuthorizationCodeCredential
- AzureCliCredential
- AzureDeveloperCliCredential
- AzurePipelinesCredential
- ChainedTokenCredential
- ClientAssertionCredential
- ClientCertificateCredential
- DeviceCodeCredential
- EnvironmentCredential
- InteractiveBrowserCredential
- ManagedIdentityCredential
- OnBehalfOfCredential
コード サンプル
Microsoft Entra サービス認証の作業サンプルについては、「ロール ベースの認証のサンプルのページを参照してください。
メッセージ配信フィードバック用のフィードバック レシーバーを開く
FeedbackReceiver を使用して、IoT Hub フィードバックに送信されたメッセージ配信を取得できます。 FeedbackReceiver
は、Receive
メソッドが Message
ではなく FeedbackBatch
を返す特殊なレシーバーです。
この例では、FeedbackReceiver
オブジェクトが作成され、フィードバックを待機するために open()
ステートメントが呼び出されます。
FeedbackReceiver feedbackReceiver = serviceClient
.getFeedbackReceiver();
if (feedbackReceiver != null) feedbackReceiver.open();
メッセージのプロパティを追加する
必要に応じて、setProperties を使用してメッセージのプロパティを追加できます。 これらのプロパティは、デバイスに送信されるメッセージに含まれており、受信時にデバイス アプリケーションによって抽出できます。
Map<String, String> propertiesToSend = new HashMap<String, String>();
propertiesToSend.put(messagePropertyKey,messagePropertyKey);
messageToSend.setProperties(propertiesToSend);
非同期メッセージを作成して送信する
Message オブジェクトは、送信するメッセージを格納します。 この例では、"クラウドからデバイスへのメッセージ" が配信されます。
setDeliveryAcknowledgement を使用して、IoT Hub メッセージ キューへの配信済み/未配信の受信確認を要求します。 この例では、要求された受信確認は Full
で、配信済みか未配信のいずれかになります。
SendAsync を使用して、クライアントからデバイスに非同期メッセージを送信します。 または、Send
(非同期ではない) メソッドを使用することもできますが、この機能は内部的に同期されるため、一度に許可される送信操作は 1 つだけです。 メッセージは、アプリケーションから IoT Hub に配信されます。 IoT Hub によってメッセージがメッセージ キューに格納され、ターゲット デバイスに配信される準備が整います。
Message messageToSend = new Message("Cloud to device message.");
messageToSend.setDeliveryAcknowledgementFinal(DeliveryAcknowledgement.Full);
serviceClient.sendAsync(deviceId, messageToSend);
メッセージ配信フィードバックを受信する
アプリケーションからメッセージが送信された後、アプリケーションはタイムアウト値を指定して、または指定せずに、receive を呼び出すことができます。 タイムアウト値が指定されていない場合は、既定のタイムアウトが使用されます。 これにより、調べることができるメッセージ配信フィードバック プロパティを含む FeedbackBatch オブジェクトが返されます。
この例では、FeedbackBatch
レシーバーを作成し、getEnqueuedTimeUtc を呼び出して、メッセージのエンキュー時間を出力します。
FeedbackBatch feedbackBatch = feedbackReceiver.receive(10000);
if (feedbackBatch != null) {
System.out.println("Message feedback received, feedback time: "
+ feedbackBatch.getEnqueuedTimeUtc().toString());
}
SDK 送信メッセージのサンプル
2 つの送信メッセージのサンプルがあります:
- サービス クライアントのサンプル - メッセージの送信の例、#1。
- サービス クライアントのサンプル - メッセージの送信の例、#2。
デバイス アプリケーションを作成する
このセクションでは、クラウドからデバイスへのメッセージを受信する方法について説明します。
IoTHubDeviceClient クラスには、デバイスから Azure IoT Hub への同期接続を作成し、IoT Hub からメッセージを受信するメソッドが含まれています。
デバイス アプリケーションを作成するには、azure-iot-device ライブラリがインストールされていなければなりません。
pip install azure-iot-device
Python ベースのデバイス アプリケーションが cloud-to-device メッセージを受信するには、IoT Hub に接続し、IoT Hub からの受信メッセージを処理するコールバック メッセージ ハンドラーを設定する必要があります。
デバイス インポート ステートメント
azure.iot.device SDK から IoTHubDeviceClient
関数をインポートするこのコードを追加します。
from azure.iot.device import IoTHubDeviceClient
デバイスを IoT Hub に接続する
デバイス アプリは、以下の方法を使用して IoT Hub で認証することができます。
- 共有アクセス キー
- X.509 証明書
重要
この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。
共有アクセス キーを使用して認証する
デバイスを IoT Hub に接続するには:
- create_from_connection_string を呼び出して、デバイスのプライマリ接続文字列を追加します。
- 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()
X.509 証明書を使用して認証する
X.509 証明書を使用してデバイスを IoT Hub に接続するには:
- create_from_x509_certificate を使用して X.509 証明書パラメーターを追加します
- connect を呼び出して、デバイス クライアントを接続します
この例では、分かりやすさのために、証明書入力パラメーターの値をローカル変数として表しています。 運用システムでは、機密性の高い入力パラメーターは環境変数やその他のより安全な保存場所に保存してください。 たとえば、os.getenv("HOSTNAME")
を使用してホスト名環境変数を読み取ります。
# The Azure IoT hub name
hostname = "xxxxx.azure-devices.net"
# The device that has been created on the portal using X509 CA signing or self-signing capabilities
device_id = "MyDevice"
# The X.509 certificate file name
cert_file = "~/certificates/certs/sensor-thl-001-device.cert.pfx"
key_file = "~/certificates/certs/sensor-thl-001-device.cert.key"
# The optional certificate pass phrase
pass_phrase = "1234"
x509 = X509(
cert_file,
key_file,
pass_phrase,
)
# The client object is used to interact with your Azure IoT hub.
device_client = IoTHubDeviceClient.create_from_x509_certificate(
hostname=hostname, device_id=device_id, x509=x509
)
# Connect to IoT Hub
await device_client.connect()
証明書認証の詳細については、以下を参照してください。
コード サンプル
デバイスの X.509 証明書認証の実際に動作するサンプルについては、非同期ハブ シナリオでファイル名が x509 で終わっている例を参照してください。
再接続を処理する
IoTHubDeviceClient
は、既定で、切断された接続の再確立を試みます。 再接続の動作は、IoTHubDeviceClient
connection_retry パラメーターと connection_retry_interval
パラメーターによって制御されます。
メッセージ ハンドラーを作成する
メッセージ ハンドラー関数を作成して、デバイスへの受信メッセージを処理します。 これは、コールバック メッセージ ハンドラーとして on_message_received
(次の手順) によって割り当てられます。
この例では、メッセージを受信したときに message_handler
が呼び出されます。 メッセージのプロパティ (.items
) は、ループを使用してコンソールに出力されます。
def message_handler(message):
global RECEIVED_MESSAGES
RECEIVED_MESSAGES += 1
print("")
print("Message received:")
# print data from both system and application (custom) properties
for property in vars(message).items():
print (" {}".format(property))
print("Total calls received: {}".format(RECEIVED_MESSAGES))
メッセージ ハンドラーを割り当てる
on_message_received メソッドを使用して、メッセージ ハンドラー メソッドを割り当てます。
この例では、message_handler
という名前のメッセージ ハンドラー メソッドが IoTHubDeviceClient
client
オブジェクトにアタッチされています。 client
オブジェクトは、IoT Hub から cloud-to-device メッセージの受信を待機します。 このコードは、メッセージを最大 300 秒 (5 分) 待機するか、キーボード キーが押されると終了します。
try:
# Attach the handler to the client
client.on_message_received = message_handler
while True:
time.sleep(300)
except KeyboardInterrupt:
print("IoT Hub C2D Messaging device sample stopped")
finally:
# Graceful exit
print("Shutting down IoT Hub Client")
client.shutdown()
SDK 受信メッセージのサンプル
メッセージの受信 - Azure IoT Hub からデバイスに送信された cloud-to-device (C2D) メッセージを受信します。
バックエンド アプリケーションを作成する
このセクションでは、クラウドからデバイスへのメッセージを送信する方法について説明します。 ソリューション バックエンド アプリケーションが IoT Hub に接続すると、メッセージは宛先デバイスでエンコードされて IoT Hub に送信されます。 IoT Hub は受信メッセージをメッセージ キューに格納し、メッセージは IoT Hub メッセージ キューからターゲット デバイスに配信されます。
IoTHubRegistryManager クラスは、サービスからクラウドからデバイスへのメッセージと対話するバックエンド アプリケーションを作成するために必要なすべてのメソッドを公開しています。 バックエンド サービス アプリケーションを作成するには、azure-iot-hub ライブラリがインストールされていなければなりません。
pip install azure-iot-hub
IoTHubRegistryManager オブジェクトをインポートする
次の import
ステートメントを追加します。 IoTHubRegistryManager には、IoT Hub Registry Manager 操作用の API が含まれています。
from azure.iot.hub import IoTHubRegistryManager
IoT Hub に接続する
次の方法を使用して、バックエンド サービスを IoT Hub に接続できます。
- 共有アクセス ポリシー
- Microsoft Entra
重要
この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>
共有アクセス ポリシーを使用して接続する
from_connection_string を使用して、IoT Hub に接続します。
次に例を示します。
IoTHubConnectionString = "{IoT hub service connection string}"
registry_manager = IoTHubRegistryManager.from_connection_string(IoTHubConnectionString)
Microsoft Entra を使用して接続する
Microsoft Entra を使用するバックエンド アプリは、IoT Hub に接続する前に、認証に成功してセキュリティ トークンの資格情報を取得する必要があります。 このトークンは、IoT Hub 接続メソッドに渡されます。 IoT Hub 用の Microsoft Entra の設定と使用に関する一般的な情報については、「Microsoft Entra ID を使用した IoT Hub へのアクセス制御」を参照してください。
Microsoft Entra アプリを構成する
優先する認証資格情報用に構成された Microsoft Entra アプリを設定する必要があります。 このアプリには、バックエンド アプリケーションで認証に使用されるクライアント シークレットなどのパラメーターが含まれています。 使用可能なアプリ認証構成は次のとおりです。
- クライアント シークレット
- [証明書]
- フェデレーション ID 資格情報
Microsoft Entra アプリでは、実行される操作に応じて、特定のロールのアクセス許可が必要になる場合があります。 たとえば、IoT Hub デバイスとモジュール ツインへの読み取りと書き込みアクセスを有効にするには、IoT Hub ツイン共同作成者が必要です。 詳細については、「Azure RBAC ロールの割り当てを使用して IoT Hub へのアクセスを管理する」を参照してください。
Microsoft Entra アプリの設定の詳細については、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。
DefaultAzureCredential を使用して認証する
Microsoft Entra を使用してバックエンド アプリケーションを認証する最も簡単な方法は、DefaultAzureCredential を使用することですが、特定の TokenCredential
や削減された ChainedTokenCredential
など、運用環境では別の方法を使用することをお勧めします。 わかりやすくするために、このセクションでは、 DefaultAzureCredential
とクライアント シークレットを使用した認証について説明します。 DefaultAzureCredential
を使用する長所と短所の詳細については、「DefaultAzureCredential の使用ガイダンス」を参照してください。
DefaultAzureCredential
では、さまざまな認証メカニズムがサポートされ、実行されている環境に基づいて適切な資格情報の種類が決まります。 有効な資格情報が見つかるまで、複数の種類の資格情報の使用を順番に試みます。
Microsoft Entra には、次の NuGet パッケージと、対応する using
ステートメントが必要です。
- Azure.Core
- Azure.Identity
using Azure.Core;
using Azure.Identity;
この例では、Microsoft Entra アプリ登録のクライアント シークレット、クライアント ID、テナント ID が環境変数に追加されます。 これらの環境変数は、アプリケーションを認証するために DefaultAzureCredential
で使用されます。 Microsoft Entra 認証が成功した結果、セキュリティ トークン資格情報が IoT Hub 接続メソッドに渡されます。
string clientSecretValue = "xxxxxxxxxxxxxxx";
string clientID = "xxxxxxxxxxxxxx";
string tenantID = "xxxxxxxxxxxxx";
Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", clientSecretValue);
Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientID);
Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantID);
TokenCredential tokenCredential = new DefaultAzureCredential();
結果として得られる TokenCredential は、Microsoft Entra 資格情報を受け入れる SDK クライアントの IoT Hub メソッドに接続するために渡すことができます。
次の例では、ServiceClient 接続オブジェクトを作成するために、TokenCredential
が ServiceClient.Create
に渡されます。
string hostname = "xxxxxxxxxx.azure-devices.net";
using var serviceClient = ServiceClient.Create(hostname, tokenCredential, TransportType.Amqp);
次の例では、RegistryManager オブジェクトを作成するために、TokenCredential
が RegistryManager.Create
に渡されます。
string hostname = "xxxxxxxxxx.azure-devices.net";
registryManager = RegistryManager.Create(hostname, tokenCredential);
コード サンプル
Microsoft Entra サービス認証の作業サンプルについては、ロール ベースの認証のサンプルのページを参照してください。
メッセージをビルドして送信する
send_c2d_message を使用して、クラウド (IoT Hub) 経由でデバイスにメッセージを送信します。
send_c2d_message
は次のパラメーターを使用します。
deviceID
- ターゲット デバイスの文字列識別子。message
- cloud-to-device メッセージ。 メッセージの種類はstr
(string) です。properties
-dict
型のプロパティの "省略可能な" コレクション。 プロパティには、アプリケーション プロパティとシステム プロパティを含めることができます。 既定値は{}
です。
この例では、ターゲット デバイスにテスト メッセージを送信します。
# define the device ID
deviceID = "Device-1"
# define the message
message = "{\"c2d test message\"}"
# include optional properties
props={}
props.update(messageId = "message1")
props.update(prop1 = "test property-1")
props.update(prop1 = "test property-2")
prop_text = "Test message"
props.update(testProperty = prop_text)
# send the message through the cloud (IoT Hub) to the device
registry_manager.send_c2d_message(deviceID, message, properties=props)
SDK 送信メッセージのサンプル
Azure IoT SDK for Python には、クラウドからデバイスへのメッセージを送信する方法を示すサービス アプリの実際のサンプルが用意されています。 詳細については、send_message.py を参照して、クラウドからデバイスへのメッセージを送信する方法を示します。
デバイス アプリケーションを作成する
このセクションでは、Azure IoT SDK for Node.js の azure-iot-device パッケージを使用して、cloud-to-device メッセージを受信する方法について説明します。
Node.js ベースのデバイス アプリケーションが cloud-to-device メッセージを受信するには、IoT Hub に接続してから、IoT Hub からの受信メッセージを処理するためのコールバック リスナーとメッセージ ハンドラーを設定する必要があります。 また、デバイスから IoT Hub へのメッセージ接続が切断された場合に備えて、デバイス アプリケーションで切断を検出して処理できる必要があります。
SDK パッケージをインストールする
azure-iot-device パッケージには、IoT デバイスとやり取りするオブジェクトが含まれています。 次のコマンドを実行して、開発マシンに azure-iot-device デバイス SDK をインストールします。
npm install azure-iot-device --save
デバイスを IoT Hub に接続する
デバイス アプリは、以下の方法を使用して IoT Hub で認証することができます。
- X.509 証明書
- 共有アクセス キー
重要
この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。
X.509 証明書を使用して認証する
X.509 証明書は、デバイスから IoT Hub への接続トランスポートにアタッチされます。
X.509 証明書を使用するデバイスから IoT Hub への接続を構成するには:
- fromConnectionString を呼び出して、デバイス接続文字列とトランスポートの種類を追加します。 デバイス接続文字列に
x509=true
を追加して、証明書がDeviceClientOptions
に追加されていることを示します。 (例:HostName=xxxxx.azure-devices.net;DeviceId=Device-1;SharedAccessKey=xxxxxxxxxxxxx;x509=true
)。 - 証明書の詳細を使用して JSON 変数を構成し、それを DeviceClientOptions に渡します。
- setOptions を呼び出して、X.509 証明書とキー (および必要に応じてパスフレーズ) をクライアント トランスポートに追加します。
- open を呼び出して、デバイスから IoT Hub への接続を開きます。
次の例は、JSON 変数内の証明書構成情報を示しています。 証明書構成に関する options
が setOptions
に渡され、open
を使用して接続が開かれます。
var options = {
cert: myX509Certificate,
key: myX509Key,
passphrase: passphrase,
http: {
receivePolicy: {
interval: 10
}
}
}
client.setOptions(options, callback);
client.open(connectCallback);
証明書認証の詳細については、以下を参照してください。
コード サンプル
デバイスの X.509 証明書認証の実際に動作するサンプルについては、「シンプルなデバイス X.509 のサンプル」を参照してください。
共有アクセス キーを使用して認証する
トランスポート プロトコルを選択する
Client
オブジェクトでは、次のプロトコルがサポートされます。
Amqp
Http
-Http
を使用する場合、Client
インスタンスは IoT Hub からのメッセージを頻繁にはチェックしません (少なくとも 25 分ごと)。Mqtt
MqttWs
AmqpWs
必要なトランスポート プロトコルを開発マシンにインストールします。
たとえば、次のコマンドを使用すると、Amqp
プロトコルをインストールできます。
npm install azure-iot-device-amqp --save
MQTT、AMQP、および HTTPS のサポートの相違点の詳細については、「cloud-to-device 通信に関するガイダンス」と「通信プロトコルの選択」を参照してください。
この例では、AMQP プロトコルを Protocol
変数に割り当てます。 このプロトコル変数は、この記事の接続文字列の追加に関するセクションの Client.fromConnectionString
メソッドに渡されます。
const Protocol = require('azure-iot-device-mqtt').Amqp;
メッセージの完了、拒否、破棄の機能
選択したプロトコルに応じて、メッセージの完了、拒否、破棄の方法を使用できます。
AMQP および HTTP
AMQP および HTTP トランスポートは、メッセージを完了、拒否、または破棄できます。
- 完了 - メッセージを完了するために、cloud-to-device メッセージを送信したサービスに、メッセージが受信されたことを通知します。 IoT Hub は、メッセージ キューからメッセージを削除します。 この方法は、
client.complete(message, callback function)
の形式をとります。 - 拒否 - メッセージを拒否するために、cloud-to-device メッセージを送信したサービスに、メッセージがデバイスによって処理されないことが通知されます。 IoT Hub は、デバイス キューからメッセージを完全に削除します。 この方法は、
client.reject(message, callback function)
の形式をとります。 - 破棄 - メッセージを破棄するために、IoT Hub はすぐに再送信を試みます。 IoT Hub は、今後使用するためにデバイス キューにメッセージを保持します。 この方法は、
client.abandon(message, callback function)
の形式をとります。
MQTT
MQTT では、メッセージの完了、拒否、または破棄の機能はサポートされていません。 代わりに、MQTT は既定でメッセージを受け入れ、メッセージは IoT Hub メッセージ キューから削除されます。
再配信の試行
デバイスがメッセージを完了、破棄、または拒否することを妨げる問題が発生した場合、IoT Hub は一定のタイムアウト期間が経過した後で、メッセージの配信をキューに入れます。 このような理由から、同じメッセージを複数回受信した場合に生成される結果が毎回同じになるように、デバイス アプリ内のメッセージ処理ロジックをべき等にする必要があります。
クライアント オブジェクトの作成
インストールされたパッケージを使用して Client
オブジェクトを作成します。
次に例を示します。
const Client = require('azure-iot-device').Client;
プロトコル オブジェクトを作成する
インストールされたトランスポート パッケージを使用して Protocol
オブジェクトを作成します。
この例では、AMQP プロトコルを割り当てます。
const Protocol = require('azure-iot-device-amqp').Amqp;
デバイスの接続文字列とトランスポート プロトコルを追加する
fromConnectionString を呼び出して、デバイス接続パラメーターを指定します。
- connStr - デバイスの接続文字列。
- transportCtor - トランスポート プロトコル。
この例では、Amqp
トランスポート プロトコルを使用します。
const deviceConnectionString = "{IoT hub device connection string}"
const Protocol = require('azure-iot-device-mqtt').Amqp;
let client = Client.fromConnectionString(deviceConnectionString, Protocol);
受信メッセージ ハンドラーを作成する
メッセージ ハンドラーは、受信メッセージごとに呼び出されます。
メッセージが正常に受信された後、AMQP または HTTP トランスポートを使用している場合は、client.complete
メソッドを呼び出して、メッセージ キューからメッセージを削除できることを IoT Hub に通知します。
たとえば、このメッセージ ハンドラーは、メッセージ ID とメッセージ本文をコンソールに出力し、client.complete
を呼び出して、メッセージを処理し、デバイス キューから安全に削除できることを IoT Hub に通知します。 MQTT トランスポートを使用している場合は、complete
の呼び出しは必要なく、省略できます。 AMQP または HTTPS トランスポートには complete
の呼び出しが必要です。
function messageHandler(msg) {
console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
client.complete(msg, printResultFor('completed'));
}
接続切断ハンドラーを作成する
接続が切断されると、切断ハンドラーが呼び出されます。 切断ハンドラーは、再接続コードを実装するのに役立ちます。
次の使用例は、切断エラー メッセージをキャッチしてコンソールに表示します。
function disconnectHandler() {
clearInterval(sendInterval);
sendInterval = null;
client.open().catch((err) => {
console.error(err.message);
});
}
イベント リスナーを追加する
次のイベント リスナーを .on メソッドを使用して指定できます。
- 接続ハンドラー
- エラー ハンドラー
- 切断ハンドラー
- メッセージ ハンドラー
この例には、前に定義したメッセージ ハンドラーと切断ハンドラーが含まれています。
client.on('connect', connectHandler);
client.on('error', errorHandler);
client.on('disconnect', disconnectHandler);
client.on('message', messageHandler);
IoT Hub への接続を開く
open メソッドを使用して、IoT デバイスと IoT Hub の間の接続を開きます。
.catch(err)
を使用してエラーをキャッチし、ハンドラー コードを呼び出します。
次に例を示します。
client.open()
.catch((err) => {
console.error('Could not connect: ' + err.message);
});
SDK デバイス サンプル
Azure IoT SDK for Node.js は、メッセージ受信を処理するデバイス アプリの動作サンプルを提供します。 詳細については、以下を参照してください:
simple_sample_device - IoT ハブに接続し、cloud-to-device メッセージを受信するデバイス アプリ。
バックエンド アプリケーションを作成する
このセクションでは、クラウドからデバイスへのメッセージを送信する方法について説明します。 前に説明したように、ソリューション バックエンド アプリケーションは IoT Hub に接続し、メッセージは宛先デバイスでエンコードされて IoT Hub に送信されます。 IoT Hub は受信メッセージをメッセージ キューに格納し、メッセージは IoT Hub メッセージ キューからターゲット デバイスに配信されます。
ソリューション バックエンド アプリケーションは、メッセージ キューを介したデバイス配信を宛先とする、IoT Hub に送信されたメッセージの配信フィードバックを要求および受信することもできます。
サービス SDK パッケージをインストールする
azure-iothub パッケージには、IoT Hub とやり取りするオブジェクトが含まれています。 この記事では、IoT Hub 経由でアプリケーションからデバイスにメッセージを送信する Client
クラス コードについて説明します。
次のコマンドを実行して、開発マシンに azure-iothub をインストールします。
npm install azure-iothub --save
クライアント モジュールとメッセージ モジュールを読み込む
azure-iothub
パッケージの Client
クラスを使用して、Client
オブジェクトを宣言します。
azure-iot-common
パッケージの Message
クラスを使用して、Message
オブジェクトを宣言します。
'use strict';
var Client = require('azure-iothub').Client;
var Message = require('azure-iot-common').Message;
IoT Hub に接続する
次の方法を使用して、バックエンド サービスを IoT Hub に接続できます。
- 共有アクセス ポリシー
- Microsoft Entra
重要
この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>
共有アクセス ポリシーを使用して接続する
fromConnectionString を使用して IoT Hub に接続します。
この例では、serviceClient
オブジェクトは、Amqp
トランスポートの種類で作成されます。
var connectionString = '{IoT hub device connection string}';
var serviceClient = Client.fromConnectionString(connectionString,`Amqp`);
クライアント接続を開く
Client
open メソッドを呼び出して、アプリケーションと IoT Hub の間の接続を開きます。
open
は、open
操作の完了時に呼び出されるコールバック関数を指定してもしなくても呼び出すことができます。
この例では、open
メソッドには、オプションの err
オープン接続コールバック関数が含まれています。 開く際にエラーが発生した場合は、エラー オブジェクトが返されます。 接続を正常に開くと、null
コールバック値が返されます。
serviceClient.open(function (err)
if (err)
console.error('Could not connect: ' + err.message);
Microsoft Entra を使用して接続する
Microsoft Entra を使用するバックエンド アプリは、IoT Hub に接続する前に、認証に成功してセキュリティ トークンの資格情報を取得する必要があります。 このトークンは、IoT Hub 接続メソッドに渡されます。 IoT Hub 用の Microsoft Entra の設定と使用に関する一般的な情報については、「Microsoft Entra ID を使用した IoT Hub へのアクセス制御」を参照してください。
Node.js SDK 認証の概要については、次を参照してください。
Microsoft Entra アプリを構成する
優先する認証資格情報用に構成された Microsoft Entra アプリを設定する必要があります。 このアプリには、バックエンド アプリケーションで認証に使用されるクライアント シークレットなどのパラメーターが含まれています。 使用可能なアプリ認証構成は次のとおりです。
- クライアント シークレット
- [証明書]
- フェデレーション ID 資格情報
Microsoft Entra アプリでは、実行される操作に応じて、特定のロールのアクセス許可が必要になる場合があります。 たとえば、IoT Hub デバイスとモジュール ツインへの読み取りと書き込みアクセスを有効にするには、IoT Hub ツイン共同作成者が必要です。 詳細については、「Azure RBAC ロールの割り当てを使用して IoT Hub へのアクセスを管理する」を参照してください。
Microsoft Entra アプリの設定の詳細については、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。
DefaultAzureCredential を使用して認証する
Microsoft Entra を使用してバックエンド アプリケーションを認証する最も簡単な方法は、DefaultAzureCredential を使用することですが、特定の TokenCredential
や削減された ChainedTokenCredential
など、運用環境では別の方法を使用することをお勧めします。 わかりやすくするために、このセクションでは、 DefaultAzureCredential
とクライアント シークレットを使用した認証について説明します。
DefaultAzureCredential
を使用する長所と短所の詳細については、「JavaScript 用 Azure ID クライアント ライブラリの資格情報チェーン」を参照してください
DefaultAzureCredential では、さまざまな認証メカニズムがサポートされ、実行されている環境に基づいて適切な資格情報の種類が決まります。 有効な資格情報が見つかるまで、複数の種類の資格情報の使用を順番に試みます。
Microsoft Entra には、次のパッケージが必要です。
npm install --save @azure/identity
この例では、Microsoft Entra アプリ登録のクライアント シークレット、クライアント ID、テナント ID が環境変数に追加されました。 これらの環境変数は、アプリケーションを認証するために DefaultAzureCredential
で使用されます。 Microsoft Entra 認証が成功した結果、セキュリティ トークン資格情報が IoT Hub 接続メソッドに渡されます。
import { DefaultAzureCredential } from "@azure/identity";
// Azure SDK clients accept the credential as a parameter
const credential = new DefaultAzureCredential();
結果として得られる資格情報トークンは、Microsoft Entra 資格情報を受け入れる SDK クライアントの IoT Hub に接続するために fromTokenCredential に渡すことができます。
fromTokenCredential
には、次の 2 つのパラメーターが必要です。
- Azure サービス URL - Azure サービスの URL は、
https://
プレフィックスのない{Your Entra domain URL}.azure-devices.net
形式にする必要があります。 たとえば、MyAzureDomain.azure-devices.net
のようにします。 - Azure 資格情報トークン
次の例では、Azure 資格情報は DefaultAzureCredential
を使用して取得されます。 その後、Azure ドメインの URL と資格情報が Registry.fromTokenCredential
に指定され、IoT Hub への接続が作成されます。
const { DefaultAzureCredential } = require("@azure/identity");
let Registry = require('azure-iothub').Registry;
// Define the client secret values
clientSecretValue = 'xxxxxxxxxxxxxxx'
clientID = 'xxxxxxxxxxxxxx'
tenantID = 'xxxxxxxxxxxxx'
// Set environment variables
process.env['AZURE_CLIENT_SECRET'] = clientSecretValue;
process.env['AZURE_CLIENT_ID'] = clientID;
process.env['AZURE_TENANT_ID'] = tenantID;
// Acquire a credential object
const credential = new DefaultAzureCredential()
// Create an instance of the IoTHub registry
hostName = 'MyAzureDomain.azure-devices.net';
let registry = Registry.fromTokenCredential(hostName,credential);
コード サンプル
Microsoft Entra サービス認証の作業サンプルについては、 Azure ID の例に関するページを参照してください。
メッセージを作成する
message オブジェクトには、cloud-to-device 非同期メッセージが含まれます。 メッセージ機能は、AMQP、MQTT、HTTP を介して同じように機能します。
メッセージ オブジェクトは、次のプロパティを含む複数のプロパティをサポートしています。 完全な一覧については、message プロパティを参照してください。
ack
- 配信フィードバック。 次のセクションで説明します。properties
- カスタム メッセージ プロパティを格納するための文字列キーと値を含むマップ。- messageId - 双方向通信の関連付けに使用します。
メッセージ オブジェクトがインスタンス化されるときに、メッセージ本文を追加します。 この例では、'Cloud to device message.'
メッセージが追加されます。
var message = new Message('Cloud to device message.');
message.ack = 'full';
message.messageId = "My Message ID";
配信確認
送信プログラムは、各 cloud-to-device メッセージに対して IoT Hub からの配信 (または有効期限) 確認を要求できます。 このオプションを使用すると、送信プログラムで通知、再試行、または補正ロジックを使用できます。 メッセージのフィードバック操作とプロパティの詳細については、「メッセージのフィードバック」を参照してください。
メッセージ フィードバックを受信する各メッセージには、配信確認の ack プロパティの値を含める必要があります。 ack
プロパティには、次の値のいずれかを指定することができます。
none (既定値): フィードバック メッセージは生成されません。
sent
: メッセージが完了した場合は、フィードバック メッセージを受信します。: デバイスが完了せずにメッセージの有効期限が切れた (または最大配信数に達した) 場合は、フィードバック メッセージを受信します。
full
: 送信された結果と送信されていない結果の両方に対するフィードバック。
この例では、ack
プロパティは full
に設定され、1 つのメッセージに対する送信済みメッセージ配信フィードバックと送信されていないメッセージ配信フィードバックの両方が要求されます。
message.ack = 'full';
メッセージ フィードバック レシーバーをリンクする
メッセージ フィードバック レシーバー コールバック関数は、getFeedbackReceiver を使用して Client
にリンクされます。
メッセージ フィードバック レシーバーは、次の 2 つの引数を受け取ります。
- エラー オブジェクト (null を指定できます)
- AmqpReceiver オブジェクト - クライアントが新しいフィードバック メッセージを受信したときにイベントを生成します。
この例の関数は、配信フィードバック メッセージを受け取ってコンソールに出力します。
function receiveFeedback(err, receiver){
receiver.on('message', function (msg) {
console.log('Feedback message:')
console.log(msg.getData().toString('utf-8'));
});
}
このコードは、getFeedbackReceiver
を使用して、receiveFeedback
フィードバック コールバック関数をサービスの Client
オブジェクトにリンクします。
serviceClient.getFeedbackReceiver(receiveFeedback);
メッセージ完了結果ハンドラーを定義する
メッセージ送信完了コールバック関数は、各メッセージが送信された後に呼び出されます。
この関数の例では、メッセージ send
操作の結果をコンソールに出力します。 この例では、printResultFor
関数は、次のセクションで説明する send
関数のパラメーターとして指定されます。
function printResultFor(op) {
return function printResult(err, res) {
if (err) console.log(op + ' error: ' + err.toString());
if (res) console.log(op + ' status: ' + res.constructor.name);
};
}
メッセージの送信
end 関数を使用して、IoT Hub 経由で非同期の cloud-to-device メッセージをデバイス アプリに送信します。
send
では、次のパラメーターがサポートされています。
- deviceID - ターゲット デバイスのデバイス ID。
- message - デバイスに送信するメッセージの本文。
- done - 操作が完了したときに呼び出す省略可能な関数。 done は 2 つの引数を指定して呼び出されます。
- エラー オブジェクト (null を指定できます)。
- トランスポート固有の応答オブジェクト。ログ記録またはデバッグに役立ちます。
次のコードは、send
を呼び出して、IoT Hub 経由で cloud-to-device メッセージをデバイス アプリに送信します。 前のセクションで定義したコールバック関数 printResultFor
は、配信確認情報を受け取ります。
var targetDevice = '{device ID}';
serviceClient.send(targetDevice, message, printResultFor('send'));
この例では、デバイスにメッセージを送信し、cloud-to-device メッセージが配信されたことの確認応答がデバイスからあったときにフィードバック メッセージを処理する方法を示します。
serviceClient.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
} else {
console.log('Service client connected');
serviceClient.getFeedbackReceiver(receiveFeedback);
var message = new Message('Cloud to device message.');
message.ack = 'full';
message.messageId = "My Message ID";
console.log('Sending message: ' + message.getData());
serviceClient.send(targetDevice, message, printResultFor('send'));
}
});
SDK 送信メッセージのサンプル
Azure IoT SDK for Node.js では、メッセージ送信タスクを処理するサービス アプリの動作サンプルが提供されます。 詳細については、以下を参照してください:
send_c2d_message.js - IoT Hub 経由で C2D メッセージをデバイスに送信します。
接続の再接続ポリシー
この記事では、デバイスから IoT Hub への接続または外部アプリケーションから IoT Hub への接続のメッセージ再試行ポリシーについては説明しません。 運用コードでは、「デバイスの再接続を管理して回復性があるアプリケーションを作成する」の説明に従って接続再試行ポリシーを実装する必要があります。
メッセージの保持時間、再試行回数、最大配信回数
「cloud-to-device メッセージを IoT Hub から送信する」で説明されているように、ポータルの IoT Hub 構成オプションまたは Azure CLI を使用して、次のメッセージ値の既定値を表示および構成できます。 これらの構成オプションは、メッセージの配信とフィードバックに影響を与える可能性があります。
- 既定の TTL (Time to Live) - デバイスが IoT Hub によって期限切れになるまでにメッセージを使用できる時間。
- フィードバックの保持時間 - IoT Hub が cloud-to-device メッセージの有効期限または配信のためにフィードバックを保持する時間。
- IoT Hub が cloud-to-device メッセージをデバイスに配信しようとした回数。