Cette bibliothèque est destinée à être utilisée avec n’importe quelle application de plateforme Windows universelle (UWP) qui doit communiquer avec d’autres applications. Je l'utilise largement dans mes applications Windows IoT personnelles exécutées sur Raspberry Pis.
Le DiscoveryClient peut être ajouté à n'importe quelle application avec seulement deux lignes :
var discoveryClient = new DiscoveryClient("1234", "4567");
discoveryClient.Initialize("My Unique Name", serializableStateObject);
La première ligne créera une instance du client avec les ports TCP et UDP souhaités sur lesquels fonctionner. La deuxième ligne définit le nom unique de ce périphérique et un pointeur vers un objet contenant toutes les informations d'état du périphérique. Il est recommandé d'utiliser un JObject. Lors du lancement, l'appareil enverra un paquet IDENTIFY et un paquet DISCOVER pour trouver tous les autres appareils sur le réseau.
Une fois le client initialisé, vous pouvez accéder aux appareils par leur nom à l'aide de LINQ :
var iotDevice = discoveryClient.Devices.FirstOrDefault(device => device.Name == "iotDeviceName");
Une fois que vous avez un objet, vous avez accès au nom, à l'adresse IP et à DeviceInfo - un objet contenant toutes les informations fournies par l'appareil.
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")}");
Étant donné que le client s'identifie au démarrage et tente de découvrir d'autres appareils, tout devrait fonctionner :) mais comme nous vivons dans le monde réel, vous souhaiterez peut-être envoyer périodiquement une demande de découverte pour vous assurer que vous connaissez tous les autres appareils. Vous pouvez le faire avec la fonction Discover().
var discoveryTimer = new Timer((state) =>
{
discoveryClient.Discover();
}, null, 0, 30000);
L'appel de Discover() diffuse un message UDP avec une liste des périphériques connus. Chaque appareil consultera la liste et répondra s'il n'est pas présent ou si son adresse IP a changé. Cela signifie également que les noms de périphériques doivent être uniques.
Parfois, vous souhaiterez savoir quand un appareil est ajouté ou quand l'état d'un appareil est mis à jour. Le client utilise des observables System.Reactive auxquels vous pouvez vous abonner :
Quand le périphérique est ajouté
using System.Reactive.Linq;
using System.Threading;
var whenDeviceAdded = discoveryClient
.WhenDeviceAdded
.ObserveOn(SynchronizationContext.Current)
.Subscribe(device =>
{
Debug.WriteLine("A device was added");
});
Quand le périphérique est mis à jour
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) est utilisé pour garantir que le code s'exécute sur le thread de l'interface utilisateur. N'oubliez pas de disposer des abonnements lorsque vous avez terminé ;)
Une fois qu'un appareil est découvert, il est possible d'envoyer des messages directement à cet appareil. Cela se fait en utilisant TCP pour garantir que le message est livré. Chaque appareil exécute une API de repos légère qui écoute les messages entrants. Un message peut être aussi simple qu'un caractère mais il est plus utile d'envoyer un objet sérialisé.
EnvoyerDirectMessage
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var jMessage = new JObject();
jMessage.Add("powerLevel", 100);
var success = await discoveryClient.SendDirectMessage("myDevice", jMessage.ToString());
QuandMessageDirect
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");
});