このライブラリは、他のアプリと通信する必要があるユニバーサル Windows プラットフォーム (UWP) アプリで使用することを目的としています。私は、Raspberry Pi 上で実行する個人的な Windows IoT アプリでこれを広く使用しています。
DiscoveryClient は、次の 2 行で任意のアプリに追加できます。
var discoveryClient = new DiscoveryClient("1234", "4567");
discoveryClient.Initialize("My Unique Name", serializableStateObject);
最初の行では、動作する必要な TCP ポートと UDP ポートを使用してクライアントのインスタンスを作成します。 2 行目は、このデバイスの一意の名前と、デバイスのすべての状態情報を保持するオブジェクトへのポインタを設定します。 JObject を使用することをお勧めします。開始時に、デバイスはネットワーク上の他のすべてのデバイスを見つけるために IDENTIFY パケットと DISCOVER パケットを送信します。
クライアントが初期化されると、LINQ を使用して名前でデバイスにアクセスできるようになります。
var iotDevice = discoveryClient.Devices.FirstOrDefault(device => device.Name == "iotDeviceName");
オブジェクトを取得すると、Name、IpAdress、および DeviceInfo (デバイスが提供する情報を含むオブジェクト) にアクセスできるようになります。
string iotDeviceIpAddress = iotDevice.IpAddress;
string iotDeviceName = iotDevice.Name;
JObject iotDeviceInfo = iotDevice.DeviceInfo;
Debug.WriteLine($"{iotDevice.Name} at {iotDevice.IpAddress} has a state of {iotDevice.DeviceInfo.GetValue<string>("state")}");
クライアントは起動時に識別し、他のデバイスの検出を試みるので、すべてがうまくいくはずです :) しかし、私たちは現実の世界に住んでいるので、他のすべてのデバイスを認識していることを確認するために、定期的に検出リクエストを送信することをお勧めします。 Discover() 関数を使用してこれを行うことができます。
var discoveryTimer = new Timer((state) =>
{
discoveryClient.Discover();
}, null, 0, 30000);
Discover() を呼び出すと、既知のデバイスのリストを含む UDP メッセージがブロードキャストされます。各デバイスはリストを参照し、存在しない場合、または IP アドレスが変更された場合に応答します。これは、デバイス名が一意である必要があることも意味します。
デバイスがいつ追加されたか、またはデバイスの状態がいつ更新されたかを知りたい場合があります。クライアントは、サブスクライブできる System.Reactive オブザーバブルを利用します。
デバイスが追加されたとき
using System.Reactive.Linq;
using System.Threading;
var whenDeviceAdded = discoveryClient
.WhenDeviceAdded
.ObserveOn(SynchronizationContext.Current)
.Subscribe(device =>
{
Debug.WriteLine("A device was added");
});
デバイスが更新されたとき
using System.Reactive.Linq;
using System.Threading;
var whenDeviceUpdated = discoveryClient
.WhenDeviceUpdated
.ObserveOn(SynchronizationContext.Current)
.Subscribe(device =>
{
Debug.WriteLine("A device was updated");
});
ObserveOn(SynchronizationContext.Current) は、コードが UI スレッド上で実行されることを確認するために使用されます。完了したら、サブスクリプションを破棄することを忘れないでください ;)
デバイスが検出されると、そのデバイスにメッセージを直接送信できます。これは TCP を利用して行われ、メッセージが確実に配信されます。各デバイスは、受信メッセージをリッスンする軽量の REST API を実行します。メッセージは文字のように単純にすることもできますが、シリアル化されたオブジェクトを送信する方が便利です。
SendDirectMessage
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var jMessage = new JObject();
jMessage.Add("powerLevel", 100);
var success = await discoveryClient.SendDirectMessage("myDevice", jMessage.ToString());
いつダイレクトメッセージ
using System.Reactive.Linq;
using System.Threading;
var whenDirectMessage = discoveryClient
.WhenDirectMessage
.ObserveOn(SynchronizationContext.Current)
.Subscribe(message => {
var jMessage = JObject.Parse(message);
var powerLevel = message.GetValue<int>("powerLevel");
});