Azure Digital Twins を Azure SignalR Service と統合する
この記事では、Azure Digital Twins と Azure SignalR Service を統合する方法について説明します。
この記事で説明するソリューションでは、1 つの Web ページやモバイル アプリケーションなどのデジタル ツインのテレメトリ データを、接続されたクライアントにプッシュすることができます。 その結果、クライアントは、サーバーをポーリングしたり更新プログラムについて新しい HTTP 要求を送信したりしなくても、IoT デバイスからのリアルタイムのメトリックと状態で更新されます。
前提条件
操作を続行する前に完了しておく前提条件を次に示します。
この記事でソリューションを Azure SignalR Service と統合する前に、Azure Digital Twins のエンドツーエンドのソリューションの接続に関するチュートリアルを完了する必要があります。それに基づいてこの操作方法の記事が作成されているからです。 そのチュートリアルでは、仮想 IoT デバイスで動作してデジタル ツインの更新をトリガーする Azure Digital Twins インスタンスを設定する手順が示されています。 この操作方法の記事では、Azure SignalR Service を使用してそれらの更新プログラムをサンプル Web アプリに接続します。
そのチュートリアルから次の値が必要になります。
- Event Grid トピック
- リソース グループ
- App Service/関数アプリの名前
お使いのコンピューターに Node.js がインストールされている必要があります。
このガイドで使用する必要があるため、自分の Azure アカウントを使用して Azure portal にサインインしてください。
サンプル アプリケーションのダウンロード
最初に、必要なサンプル アプリをダウンロードします。 次の両方のサンプルが必要です。
Azure Digital Twins のエンドツーエンド サンプル: このサンプルには、Azure Digital Twins インスタンス内でデータを移動するための 2 つの Azure 関数を保持する AdtSampleApp が含まれています (このシナリオの詳細については、エンドツーエンドのソリューションの接続に関するチュートリアルで学習できます)。 また、IoT デバイスをシミュレートし、1 秒ごとに新しい温度値を生成する DeviceSimulator サンプル アプリケーションも含まれています。
「前提条件」にあるチュートリアルの一部としてサンプルをまだダウンロードしていない場合は、サンプルにアクセスし、タイトルの下にある [コードの参照] ボタンを選択してください。 これにより、サンプル用の GitHub リポジトリに移動します。[Code]\(コード\) ボタンと、[Download ZIP]\(ZIP のダウンロード\) を選択することによって、.zip 形式でこれをダウンロードできます。
このボタンにより、お使いのマシンにサンプル リポジトリのコピーが digital-twins-samples-main.zip としてダウンロードされます。 フォルダーを解凍します。
SignalR 統合 Web アプリのサンプル: このサンプルの React Web アプリでは、Azure SignalR Service からの Azure Digital Twins テレメトリ データが使用されます。
- サンプル リンクに移動し、同じダウンロード プロセスを使用してサンプルのコピーをお使いのコンピューターに digitaltwins-signalr-webapp-sample-main.zip としてダウンロードします。 フォルダーを解凍します。
ソリューションのアーキテクチャ
以下のパスを使用して、Azure SignalR Service を Azure Digital Twins に接続します。 図の A、B、C の各セクションは、エンド ツー エンドのチュートリアルの事前準備のアーキテクチャ図から引用したものです。 この操作方法に関する記事では、SignalR およびクライアント アプリと通信する 2 つの新しい Azure 関数を含む既存のアーキテクチャにセクション D を作成します。
Azure SignalR インスタンスを作成する
次に、「Azure SignalR Service のインスタンスを作成する」の手順に従って、この記事で使用する Azure SignalR インスタンスを作成します (現時点では、このセクションの手順のみを完了します)。
次のセクションでもう一度使用するので、Azure portal のブラウザー ウィンドウは開いたままにしておきます。
Azure Functions アプリの発行と構成
このセクションでは、次の 2 つの Azure 関数を設定します。
- negotiate - HTTP トリガー関数。 SignalRConnectionInfo 入力バインドを使用して有効な接続情報を生成し、返します。
- broadcast - Event Grid トリガー関数。 Event Grid から Azure Digital Twins テレメトリ データを受信し、前の手順で作成した SignalR インスタンスの出力バインドを使用して、接続されているすべてのクライアント アプリケーションにメッセージをブロードキャストします。
Visual Studio または任意の別のコード エディターを起動し、digital-twins-samples-main\ADTSampleApp フォルダー内のコード ソリューションを開きます。 その後、次の手順を実行して関数を作成します。
SampleFunctionsApp プロジェクトに SignalRFunctions.cs と呼ばれる新しい C# クラスを作成します。
このクラス ファイルの内容を次のコードに置き換えます。
using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.Azure.WebJobs.Extensions.EventGrid; using Microsoft.Azure.WebJobs.Extensions.SignalRService; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Azure.Messaging.EventGrid; namespace SignalRFunction { public static class SignalRFunctions { public static double temperature; [FunctionName("negotiate")] public static SignalRConnectionInfo GetSignalRInfo( [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req, [SignalRConnectionInfo(HubName = "dttelemetry")] SignalRConnectionInfo connectionInfo) { return connectionInfo; } [FunctionName("broadcast")] public static Task SendMessage( [EventGridTrigger] EventGridEvent eventGridEvent, [SignalR(HubName = "dttelemetry")] IAsyncCollector<SignalRMessage> signalRMessages, ILogger log) { JObject eventGridData = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString()); log.LogInformation($"Event grid message: {eventGridData}"); var patch = (JObject)eventGridData["data"]["patch"][0]; if (patch["path"].ToString().Contains("/Temperature")) { temperature = Math.Round(patch["value"].ToObject<double>(), 2); } var message = new Dictionary<object, object> { { "temperatureInFahrenheit", temperature}, }; return signalRMessages.AddAsync( new SignalRMessage { Target = "newMessage", Arguments = new[] { message } }); } } }
Visual Studio の [パッケージ マネージャー コンソール] ウィンドウ、またはお使いのマシンの任意のコマンド ウィンドウで、フォルダー digital-twins-samples-main\AdtSampleApp\SampleFunctionsApp に移動し、次のコマンドを実行して
SignalRService
NuGet パッケージをプロジェクトにインストールします。dotnet add package Microsoft.Azure.WebJobs.Extensions.SignalRService --version 1.14.0
このコマンドを実行すると、そのクラスに含まれる依存関係の問題が解決されます。
任意の方法を使用して、関数を Azure に発行します。
Visual Studio を使用して関数を発行する方法については、「Visual Studio を使用する Azure Functions の開発」を参照してください。 Visual Studio Code を使用して関数を発行する方法については、「Visual Studio Code を使用して Azure に C# 関数を作成する」を参照してください。 Azure CLI を使用して関数を発行する方法については、「Azure でコマンド ラインから C# 関数を作成する」を参照してください。
関数を構成する
次に、Azure SignalR インスタンスと通信するように関数を構成します。 まず、SignalR インスタンスの接続文字列を収集し、関数アプリの設定に追加します。
Azure portal にアクセスし、ポータルの上部にある検索バーで SignalR インスタンスの名前を検索します。 インスタンスを選択して開きます。
インスタンスのメニューから [キー] を選択して、SignalR Service インスタンスの接続文字列を表示します。
[コピー] アイコンを選び、[プライマリ接続文字列] をコピーします。
最後に、次の Azure CLI コマンドを使用して、Azure SignalR の接続文字列を関数のアプリ設定に追加します。 また、プレースホルダーを、チュートリアルの前提条件のリソース グループと App Service/関数アプリの名前に置き換えます。 このコマンドは、Azure Cloud Shell で実行するか、Azure CLI がマシンにインストールされている場合はローカルで実行できます。
az functionapp config appsettings set --resource-group <your-resource-group> --name <your-function-app-name> --settings "AzureSignalRConnectionString=<your-Azure-SignalR-ConnectionString>"
このコマンドの出力では、Azure 関数用に設定されたすべてのアプリ設定が出力されます。 一覧の下部で
AzureSignalRConnectionString
を検索して、それが追加されていることを確認します。
Event Grid に関数を接続する
次に、broadcast Azure 関数を Event Grid トピック (チュートリアルの前提条件で作成) でサブスクライブします。 このアクションにより、テレメトリ データは thermostat67 ツインから Event Grid トピックを経て関数へと流れることができます。 ここから、この関数によってすべてのクライアントにそのデータをブロードキャストできます。
データをブロードキャストするには、Event Grid トピックからエンドポイントとしての broadcast Azure 関数へのイベント サブスクリプションを作成します。
Azure portal の上部の検索バーで、Event Grid トピックの名前を検索してそのトピックに移動します。 [+ イベント サブスクリプション] を選択します。
[イベント サブスクリプションの作成] ページで、各フィールドに次のように入力します (既定値が入力されるフィールドは省略しています)。
- [イベント サブスクリプションの詳細]>[名前]: イベント サブスクリプションに名前を付けます。
- [エンドポイントの詳細]>[エンドポイントの種類]: メニュー オプションから [Azure 関数] を選択します。
- [エンドポイントの詳細]>[エンドポイント]: [エンドポイントの選択] リンクを選択して、[Azure 関数の選択] ウィンドウを開きます。
- [サブスクリプション]、[リソース グループ]、[関数アプリ]、[関数] (broadcast) を入力します。 これらのフィールドの一部は、サブスクリプションの選択後に自動的に設定される場合があります。
- [選択の確認] を選択します。
再び [イベント サブスクリプションの作成] ページで、 [作成] を選択します。
この時点で、[Event Grid Topic]\(Event Grid トピック\) ページに 2 つのイベント サブスクリプションが表示されます。
Web アプリの構成と実行
このセクションでは、動作中の結果を見ていきます。 まず、設定しておいた Azure SignalR のフローに接続するようにサンプル クライアント Web アプリを構成します。 次に、Azure Digital Twins インスタンスを介してデバイス テレメトリ データを送信するシミュレートされたデバイス サンプル アプリを起動します。 その後、サンプル Web アプリを表示して、サンプル Web アプリをリアルタイムで更新するシミュレートされたデバイス データを確認します。
サンプル クライアント Web アプリを構成する
次に、サンプル クライアント Web アプリを構成します。 まず negotiate 関数の HTTP エンドポイント URL を収集し、それを使用してお使いのコンピューター上でアプリ コードを構成します。
Azure portal の [関数アプリ] ページにアクセスし、一覧から関数アプリを選択します。 アプリ メニューで、[関数] を選択し、negotiate 関数を選択します。
[関数の URL の取得] を選択し、/api までの値 (最後の /negotiate? は含めないでください) をコピーします。 次の手順でこの値を使用します。
Visual Studio または任意のコード エディターを使用して、「サンプル アプリケーションのダウンロード」セクションでダウンロードした解凍済みの digitaltwins-signalr-webapp-sample-main フォルダーを開きます。
src/App.js ファイルを開き、
HubConnectionBuilder
内の関数 URL を、前の手順で保存した negotiate 関数の HTTP エンドポイント URL に置き換えます。const hubConnection = new HubConnectionBuilder() .withUrl('<Function-URL>') .build();
Visual Studio の "開発者コマンド プロンプト" またはコンピューター上の任意のコマンド ウィンドウで、digitaltwins-signalr-webapp-sample-main\src フォルダーに移動します。 次のコマンドを実行して、依存ノード パッケージをインストールします。
npm install
次に、Azure Portal で関数アプリでのアクセス許可を設定します。
Azure portal の [関数アプリ] ページで、関数アプリ インスタンスを選択します。
インスタンスのメニューを下にスクロールし、[CORS] を選択します。 [CORS] ページで、空のボックスに
http://localhost:3000
を入力して、許可された配信元として追加します。 [Access-Control-Allow-Credentials を有効にする] ボックスをオンにして、[保存] を選択します。
デバイス シミュレーターを実行する
エンド ツー エンドのチュートリアルの事前準備では、IoT Hub を介してデータを Azure Digital Twins インスタンスに送信するようにデバイス シミュレーターを構成しました。
ここでは、digital-twins-samples-main\DeviceSimulator\DeviceSimulator.sln にあるシミュレーター プロジェクトを開始します。 Visual Studio を使用している場合は、プロジェクトを開いてから、ツール バーにあるこのボタンを使用して実行できます。
コンソール ウィンドウが開いて、シミュレートされたデバイスの温度テレメトリ メッセージが表示されます。 これらのメッセージは Azure Digital Twins インスタンスを介して送信され、そこでその後、Azure 関数と SignalR によって取得されます。
このコンソールで行うべき作業は他にありませんが、次のステップに取り組む間、コンソールは実行したままにしておいてください。
結果の表示
動作中の結果を確認するには、SignalR 統合 Web アプリのサンプルを起動します。 そのためには、任意のコンソール ウィンドウから、digitaltwins-signalr-webapp-sample-main\src の場所で、次のコマンドを実行します。
npm start
このコマンドを実行すると、サンプル アプリが実行されているブラウザー ウィンドウが開き、ビジュアル温度計が表示されます。 アプリが実行されると、Azure Digital Twins を介して伝達されるデバイス シミュレーターからの温度テレメトリの値が、Web アプリによってリアルタイムで反映されるのを確認できるようになります。
リソースをクリーンアップする
この記事で作成したリソースがもう必要ない場合は、次の手順に従って削除します。
Azure Cloud Shell またはローカルの Azure CLI から az group delete コマンドを使用すると、リソース グループ内の Azure リソースをすべて削除できます。 リソース グループを削除すると、以下も削除されます。
- Azure Digital Twins インスタンス (エンド ツー エンドのチュートリアルから)
- IoT Hub とハブのデバイス登録 (エンド ツー エンドのチュートリアルから)
- Event Grid トピックと関連付けられているサブスクリプション
- Azure Functions アプリ (3 つのすべての関数と、ストレージなどの関連リソースを含む)
- Azure SignalR インスタンス
重要
リソース グループを削除すると、元に戻すことができません。 リソース グループとそこに含まれるすべてのリソースは完全に削除されます。 間違ったリソース グループやリソースをうっかり削除しないようにしてください。
az group delete --name <your-resource-group>
最後に、ローカル コンピューターにダウンロードしたプロジェクトのサンプル フォルダー (digital-twins-samples-main.zip、digitaltwins-signalr-webapp-sample-main.zip と、これらを解凍したもの) を削除します。
次のステップ
この記事では、Azure Digital Twins のテレメトリ イベントをサンプル クライアントアプリケーションにブロードキャストするように、SignalR で Azure 関数を設定しました。
次に、Azure SignalR Service の詳細を確認します。
または、Azure Functions を使用した Azure SignalR Service 認証の詳細を確認します。