Эта библиотека предназначена для использования с любым приложением универсальной платформы Windows (UWP), которому необходимо взаимодействовать с другими приложениями. Я широко использую его в своих личных приложениях Windows IoT, работающих на Raspberry Pis.
DiscoveryClient можно добавить в любое приложение всего двумя строками:
var discoveryClient = new DiscoveryClient("1234", "4567");
discoveryClient.Initialize("My Unique Name", serializableStateObject);
Первая строка создаст экземпляр клиента с нужными портами TCP и UDP для работы. Вторая строка задает уникальное имя этого устройства и указатель на объект, содержащий всю информацию о состоянии устройства. Рекомендуется использовать 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");
});
КогдаDeviceUpdated
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) используется для обеспечения выполнения кода в потоке пользовательского интерфейса. Не забудьте избавиться от подписок, когда закончите ;)
Как только устройство обнаружено, можно отправлять сообщения непосредственно на это устройство. Это делается с использованием TCP, чтобы гарантировать доставку сообщения. На каждом устройстве работает облегченный API для отдыха, который прослушивает входящие сообщения. Сообщение может быть таким же простым, как символ, но полезнее отправлять сериализованный объект.
Отправитьпрямое сообщение
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");
});