Esta biblioteca deve ser usada com qualquer aplicativo UWP (Plataforma Universal do Windows) que precise se comunicar com outros aplicativos. Eu o uso extensivamente em meus aplicativos pessoais do Windows IoT em execução no Raspberry Pis.
O DiscoveryClient pode ser adicionado a qualquer aplicativo com apenas duas linhas:
var discoveryClient = new DiscoveryClient("1234", "4567");
discoveryClient.Initialize("My Unique Name", serializableStateObject);
A primeira linha criará uma instância do cliente com as portas TCP e UDP desejadas para operar. A segunda linha define o nome exclusivo deste dispositivo e um ponteiro para um objeto que contém todas as informações de estado do dispositivo. É recomendado que você use um JObject. Após a inicialização, o dispositivo enviará um pacote IDENTIFY e um pacote DISCOVER para localizar todos os outros dispositivos na rede.
Depois que o cliente for inicializado, você poderá acessar os dispositivos pelo nome usando LINQ:
var iotDevice = discoveryClient.Devices.FirstOrDefault(device => device.Name == "iotDeviceName");
Depois de ter um objeto, você terá acesso a Name, IpAdress e DeviceInfo - um objeto que contém qualquer informação fornecida pelo dispositivo.
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")}");
Como o cliente se identifica na inicialização e tenta descobrir outros dispositivos, tudo deve funcionar :) mas como vivemos no mundo real, você pode querer enviar periodicamente uma solicitação de descoberta para ter certeza de que está ciente de todos os outros dispositivos. Você pode fazer isso com a função Discover().
var discoveryTimer = new Timer((state) =>
{
discoveryClient.Discover();
}, null, 0, 30000);
Chamar Discover() transmite uma mensagem UDP com uma lista de dispositivos conhecidos. Cada dispositivo examinará a lista e responderá se não estiver presente ou se seu endereço IP tiver sido alterado. Isso também significa que os nomes dos dispositivos devem ser exclusivos.
Às vezes você vai querer saber quando um dispositivo é adicionado ou quando o estado de um dispositivo é atualizado. O cliente utiliza observáveis System.Reactive que você pode assinar:
QuandoDispositivoAdicionado
using System.Reactive.Linq;
using System.Threading;
var whenDeviceAdded = discoveryClient
.WhenDeviceAdded
.ObserveOn(SynchronizationContext.Current)
.Subscribe(device =>
{
Debug.WriteLine("A device was added");
});
Quando o dispositivo é atualizado
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) é usado para garantir que o código seja executado no thread da UI. Não se esqueça de descartar as assinaturas quando terminar;)
Depois que um dispositivo é descoberto, é possível enviar mensagens diretamente para esse dispositivo. Isso é feito utilizando TCP para garantir que a mensagem seja entregue. Cada dispositivo executa uma API de descanso leve que escuta as mensagens recebidas. Uma mensagem pode ser tão simples quanto um caractere, mas é mais útil enviar um objeto serializado.
EnviarMensagem Direta
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var jMessage = new JObject();
jMessage.Add("powerLevel", 100);
var success = await discoveryClient.SendDirectMessage("myDevice", jMessage.ToString());
QuandoDirectMessage
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");
});