Sommaire
Fonctionnement de base
Comme nous l’avons vu dans le tutoriel précèdent, un package est une application !
Il faut impérativement appeler la méthode “PackageHost.Start” au démarrage de l’application, c’est à dire dans la méthode “Main” autrement, ce n’est pas un package Constellation mais une simple application .NET !
Lorsque vous appelez la méthode “PackageHost.Start” vous devez impérativement transférer les arguments (args) et indiquer la classe de votre package (ici nommée “MonPackage”).
1 2 3 4 |
static void Main(string[] args) { PackageHost.Start<MonPackage>(args); } |
La classe d’un package doit être une classe qui implémente l’interface “IPackage”. Cette interface définit trois méthodes :
-
OnStart qui sera invoqué lorsque le package a démarré
-
OnPreShutdown : invoqué lorsque le package va s’arrêter (à ce stade votre package est toujours connecté à Constellation, vous pouvez encore pusher des StateObjects, envoyer des messages, écrire des logs sur le hub, etc..)
-
OnShutdown : invoqué après le OnPreShutdown et après avoir fermé les connexions (plus aucune interaction avec la Constellation possible)
Pour vous éviter de devoir implémenter ces trois méthodes, votre classe peut hériter de la classe “PackageBase”. Cette classe abstraite implémente l’interface IPackage dans des méthodes virtuelles vides.
Libre à vous d’implémenter les méthodes que vous souhaitez !
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class MonPackage : PackageBase { //public override void OnStart() //{ //} //public override void OnPreShutdown() //{ //} //public override void OnShutdown() //{ //} } |
Ecrire des logs
Pour écrire des logs depuis un package Constellation vous disposez des méthodes suivantes :
- PackageHost.WriteDebug
- PackageHost.WriteInfo
- PackageHost.WriteWarn
- PackageHost.WriteError
Chacune de ces méthodes écrivent un message qui peut être formaté avec des arguments à la manière d’un “string.Format” :
1 |
PackageHost.WriteInfo("Je suis le package nommé {0} version {1}", PackageHost.PackageName, PackageHost.PackageVersion); |
Attention : bien respecter les index dans le format de votre message sous peine d’avoir une erreur.
Pour éviter cela, vous pouvez depuis C# 6.0 (intégré nativement depuis Visual Studio 2015), utiliser les « chaines interpolée » en plaçant en début de chaine un « $ » afin de pouvoir placer les arguments directement dans la chaine :
1 |
PackageHost.WriteInfo($"Je suis le package nommé {PackageHost.PackageName} version {PackageHost.PackageVersion}"); |
Note : la méthode WriteDebug écrit seulement dans la console (mode debug local). Les logs de type “Debug” ne sont jamais envoyés dans la Constellation.
Propriétés du PackageHost
La classe centrale “PackageHost” expose différentes propriétés pour votre package Constellation.
PackageHost.IsRunning
Il s’agit d’un booléen qui indique si votre package est démarré. Il est affecté à “true” juste avant le OnStart et passe à “false” juste avant le OnPreShutdown.
Cela vous permet de connaitre l’état de votre package et sert notamment pour interrompre des boucles :
1 2 3 4 |
while (PackageHost.IsRunning) { // Do job } |
PackageHost.IsStandAlone
Cette propriété vous indique si votre package est démarré en “stand-alone”, c’est à dire lancé manuellement (en lançant le EXE) ou via Visual Studio (Debug on Constellation).
Si le package est démarré depuis une sentinelle Constellation, cette propriété est à “false”.
PackageHost.IsConnected
Vous indiques si le package est connecté ou non à la Constellation.
PackageHost.ConstellationHub
Retourne le proxy SignalR du hub Constellation.
PackageHost.HasControlManager
Indique si le package est connecté au hub de contrôle.
PackageHost.ControlManager
Retourne le client du hub de contrôle permettant de contrôler la Constellation. (plus d’information)
Cette propriété est nulle si votre package ne demande pas de connexion au hub de contrôle. Vous devez donc tester si le client est disponible ou non avec la propriété ci-dessus :
1 2 3 4 |
if (PackageHost.HasControlManager) { PackageHost.ControlManager.xxxx(); } |
PackageHost.Package
Retourne l’instance de votre package.
PackageHost.PackageDescriptor
Retourne l’instance du PackageDescriptor qui contient la description de vos MessagesCallbacks et StateObjects.
PackageHost.PackageName
Retourne le nom du package.
Le nom du package est défini dans le manifeste du package (PackageInfo.xml). Si aucune valeur n’est trouvée, le nom du package est le nom de l’assembly .NET du package.
PackageHost.PackageInstanceName
Retourne le nom de l’instance du package, c’est à dire le nom défini sur le serveur.
Un même package peut avoir plusieurs instances sur une même sentinelle mais avec des noms de package différents.
PackageHost.SentinelName
Retourne le nom de la sentinelle qui a démarré le package (si IsStandAlone = false).
Cette propriété est nulle si le package est démarré manuellement (en lançant le EXE) ou égale à “Developer” si lancé depuis Visual Studio.
PackageHost.PackageVersion
Retourne le numéro de version du package tel que défini dans le manifeste du package. Si il n’y a pas de manifeste, elle retourne le “PackageAssemblyVersion”.
PackageHost.PackageAssemblyVersion
Retourne le numéro de version de l’assembly du package.
PackageHost.ConstellationClientVersion
Retourne le numéro de version de la librairie Constellation utilisée par le package.
PackageHost.PackageManifest
Retourne le manifeste du package. (plus d’information)
PackageHost.Settings
Retourne les settings du packages. (plus d’information)
Connexion à Constellation
Pour savoir si votre package est connecté à Constellation, vous pouvez interroger la propriété “PackageHost.IsConnected” comme indiqué ci-dessus.
Vous avez également l’évènement “ConnectionStateChanged” qui se déclenche lorsque le statut de la connexion change :
1 2 3 4 5 6 7 8 9 10 11 12 |
PackageHost.ConnectionStateChanged += (s, e) => { if (PackageHost.IsConnected) { // Récupération de la connexion // TODO : MAJ des états ? } else { // Perte de la connexion } }; |
Notez que lors de la première connexion cet événement n’est pas levé car Constellation n’a pas encore invoqué la méthode “OnStart” de votre package. Autrement dit le package se connecte d’abord puis “vous donnes la main”.
Donc si l’événement “ConnectionStateChanged“ est déclenché et que la propriété PackageHost.IsConnected = true, c’est qu’il s’agit forcement d’une reconnexion !
Dans ce cas, et en fonction de votre package, il est recommandé de “mettre à jour l’état” de votre package en re-pushant vos StateObjects.
Exemple :
Vous développez un package Constellation qui fait le lien vers votre système d’alarme.
Chaque zone de votre alarme est publiée dans Constellation sous forme de StateObject. Vous avez donc autant de StateObject que de zone et chacun de ces StateObjects indique l’état d’une zone de l’alarme (ouverte ou fermée).
Si pour une raison ou pour une autre, la connexion entre le package et la Constellation est rompue, l’activité sur les zones de l’alarme ne peut donc plus être mis à jours.
C’est pour cela que lorsque votre package parvient à se reconnecter il peut être nécessaire de republier tous les StateObjects sur Constellation pour être sûr d’avoir des StateObjects à jour par rapport à votre système d’alarme.
Démarrez la discussion sur le forum Constellation