Implémenter un service d’événements avec le Micro Framework .Net

14 février 2009 23:00 par Jean-Michel Guemguem

Informer du déclenchement d’un événement est un des besoins que l’on rencontre sur des petits équipements.

Avec la dernière version du SDK du Micro Framework (version 3.0), répondre à ce besoin est devenu plus simple à mettre en œuvre. Son outil MFSvcUtil permet de générer du code pour implémenter une pile DPWS (Devices Profile for Web Services). La publication de services d’événements est une des fonctionnalités de DPWS en s’appuyant sur le protocole WS-Eventing.

Prenons comme exemple un portier d’accueil avec une sonnette. Un des besoins de ce portier est d’indiquer sur l’intranet que l’on sonne à la porte. Une des solutions est d’implémenter un service d’événements pour diffuser le message de sonnerie :

  • Définir manuellement le service d’événement de la sonnerie dans le fichier SonnerieService.wsdl (l’événement SonerieEvent transmet un message texte)
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="SonnerieService"
                  xmlns:tns="http://portier.device.tekigo.net/SonnerieService"
                  xmlns:xs="http://www.w3.org/2001/XMLSchema"
                  targetNamespace="http://portier.device.tekigo.net/SonnerieService"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
                  xmlns:wse="http://schemas.xmlsoap.org/ws/2004/08/eventing">
  
  <!-- Types des données echangées dans les requetes/reponses -->
  <wsdl:types>
    <xs:schema elementFormDefault="qualified"
              targetNamespace="http://portier.device.tekigo.net/SonnerieService">
      <!-- Type pour la reponse de SonnerieEvent : string -->
      <xs:element name="AlerteSonnerieResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element minOccurs="1" maxOccurs="1" name="textSonnerie" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
  </wsdl:types>
 
  <!-- Messages avec le type de données -->
  <wsdl:message name="SonnerieEventOut">
    <wsdl:part name="alerte" element="tns:AlerteSonnerieResponse" />
  </wsdl:message>
 
  <!-- Méthodes événements -->
  <wsdl:portType name="SonnerieService" wse:EventSource="true" >
    <wsdl:operation name="SonnerieEvent" >
      <wsdl:output message="tns:SonnerieEventOut" />
    </wsdl:operation>
  </wsdl:portType>
  
  <!-- Transport -->
  <wsdl:binding name="PortierServicesSoap12" type="tns:SonnerieService">
    <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="SonnerieEvent">
      <soap12:operation soapAction="http://portier.device.tekigo.net/SonnerieService/SonnerieEvent" soapActionRequired="true"/>
      <wsdl:input>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
</wsdl:definitions>
  • Exécuter l’outil MFSvcUtil pour générer le code C# des classes du service (contrat et hébergement du service).
"C:\Program Files\Microsoft .NET Micro Framework\v3.0\Tools\MFSvcUtil.exe" SonnerieService.wsdl /V
  • Initialiser DPWS (à appeler au lancement de l’application)
   1: /// <summary>
   2: /// Initialise les services web pour devices
   3: /// </summary>
   4: private void InitialiserDpws()
   5: {
   6:     // Définition des metadonnées
   7:     // Description du modéle
   8:     Device.ThisModel.Manufacturer = "Tekigo";
   9:     Device.ThisModel.ManufacturerUrl = "http://www.tekigo.com/";
  10:     Device.ThisModel.ModelName = "Portier d'accueil";
  11:     Device.ThisModel.ModelNumber = "1.0";
  12:     Device.ThisModel.ModelUrl = "http://www.tekigo.com/";
  13:     Device.ThisModel.PresentationUrl = "http://www.tekigo.com/";
  14:     // Description de l'équipement
  15:     Device.ThisDevice.FriendlyName = "Sonnette avec panneau d'affichage";
  16:     Device.ThisDevice.FirmwareVersion = "0.5.1";
  17:     Device.ThisDevice.SerialNumber = "TEKIGO-0001";
  18:  
  19:     // Services hébergés par DPWS
  20:     EcranServiceImplementation ecran = new EcranServiceImplementation(new EcranServiceImplementation.MessageCallback(AfficherInformation));
  21:     _dpwsEcran = new EcranService(ecran);
  22:     Device.HostedServices.Add(_dpwsEcran);
  23:     _dpwsSonnerie = new SonnerieService();
  24:     Device.HostedServices.Add(_dpwsSonnerie);
  25:  
  26:     // Pour ne pas prendre en compte les requetes locales
  27:     Device.IgnoreLocalClientRequest = true;
  28:  
  29:     // Lancement de DPWS
  30:     Device.Start();
  31: }
  • Déclencher le service d’événements lors de la sonnerie
   1: /// <summary>
   2: /// Déclenche l'événement SonnerieEvent du service SonnerieService (DPWS)
   3: /// </summary>
   4: private void OnButtonUp(object sender, ButtonEventArgs e)
   5: {
   6:     // Message texte diffusé par l'événement
   7:     AlerteSonnerieResponse sonnerie = new AlerteSonnerieResponse();
   8:     sonnerie.textSonnerie = DateTime.Now.ToString() + " On sonne à la porte";
   9:  
  10:     // Déclenche l'événement de sonnerie  
  11:     _dpwsSonnerie.SonnerieEvent(sonnerie);
  12: }

La mise en œuvre du service d’événements sur un petit équipement piloté par le Micro Framework est donc bien facilitée. Par contre la réalisation d’un client côté PC l’est beaucoup moins, car pour l’heure seuls Windows Vista, Windows Serveur 2008 et Windows 7 implémentent nativement une pile DPWS. Le SDK de Windows Serveur 2008 fournit l’API de développement WSDAPI. avec deux exemples en code natif, mais rien en code managé. La prochaine version de WCF devrait combler ce manque.