Frédéric Colin
Windows Media Center et WCF : développez votre maison intelligente
Le développement d'applications pour Windows Media Center est facilité avec l'arrivée du SDK 5.3. Même si l'on sent un modèle objet bien lourd derrière, il devient plus facile d'exposer les fonctionnalités de WMC sous la forme de services WCF.
Par Frédéric Colin publié le 23/06/2008 à 08:04, lu 1395 fois, 10 pages
 6 | Les Contrats
Les contrats de données viennent décrire la structure des messages qui seront échangés entre les clients et les services. Ils sont complètement décorelés de l'implémentation des services qui s'en servent afin d'être sérialisés en fonction d'un schéma précis. Pour l'exemple qui nous intéresse, j'ai simplement reproduit un sous-ensemble du modèle objet fourni par Windows Media Center sur la notion de Guide. Le Guide représente la liste des programmes TV associés aux chaines. Il y a deux types de contrats :
  • Le contrat concernant le guide des programmes TV
     
    Contrat de données Guide

    Contrat de données Guide

     
    Globalement ce qu'il faut retenir de ce contrat de données, c'est que les informations sont regroupées par chaînes TV (« Channel »), qu'une partie des informations d'une chaîne est contenue dans une classé composée (« Service »). Ensuite, une chaîne contient une liste de planifications (« ScheduleEntry »), chaque planification étant composée d'un programme (« Program »).

    D'un point de vue technique, les contrats de données sont rendus sérialisables dans le sens WCF du terme par décoration avec les attributs « DataContract » et « DataMember » issus de l'Assembly « System.RuntimeSerialization » :

    [DataContract(Namespace = "http://www.bewise.fr/2008/05/THB")]

    public class Channel

    {

        [DataMember()]

        public string Id

        { get; set; }

     

        [DataMember()]

        public bool IsActive

        { get; set; }

     

      Etc.

    }

  • Le contrat de données concernant la gestion de la télécommande permet de décrire la liste des commandes du contrôle à distance acceptées via un type énuméré qui sera décoré avec les attributs « DataContract » et « EnumMember » :

    [DataContract()]

    public enum CommandListOption : ushort

    {

        [EnumMember]

        NAVIGATE_GUIDE = 0x47,

        [EnumMember]

        NAVIGATE_LIVE_TV = 0x54,

        [EnumMember]

        NAVIGATE_MUSIC = 0x4d,

        [EnumMember]

     

      Etc.

    }

     
    Contrat de données commande TV

    Contrat de données commande TV

     
Les contrats de services viennent décrire les contrats dans le sens « Interface » du terme. Ils seront implémentés par la couche service et seront rendus accessibles via WCF. Pour l'exemple, j'ai retenu deux contrats :
  • Le contrat de gestion de Windows Media Center :
     
    Contrat de service WMC

    Contrat de service WMC

     
    Les noms des services ont des méthodes éponymes qui ne méritent pas plus de description. La seule information à donner concerne le service « GetGuide » qui est surchargé et qui renvoie l'ensemble du guide ou bien une partie du guide en fonction d'une plage de date. Le service « StandBy » permet de mettre en veille le PC.
  • Le contrat permettant de récupérer via un service WCF la page HTML contenant l'interface de la télécommande.
     
    Contrat de service gestion IHM

    Contrat de service gestion IHM

     
C'est à cet endroit que la notion de service REST est définie. Effectivement, le Framework .NET 3.5 ajoute de nouveaux attributs à positionner, rendant accessibles les services via une architecture de type REST. Encore une fois, nous nous contentons de décorer plutôt que de coder la tuyauterie et c'est le processus porteur qui se chargera d'exposer les services et ce, de manière transparente pour le développeur.

Ce qui nous donne pour le contrat de gestion du Media Center :
 
Code du contrat de service

Code du contrat de service

 
Au niveau REST, J'ai volontairement choisi d'utiliser l'attribut « WebInvoke » en lieu et place du classique « WebGet » afin de réaliser les appels en HTTP / POST plutôt qu'en HTTP / GET, ce afin d'éviter toute problématique de cache des navigateurs Web du marché.

En effet, les requêtes HTTP / GET sont souvent mises en cache du côté du navigateur afin d'éviter les allers-retours inutiles sur le serveur Web pour les requêtes HTTP / GET identiques d'un point de vue de l'URL. Ce qui n'est pas sans poser un réel problème avec XMLHttpRequest qui bénéficie lui aussi de ce cache lorsque l'on souhaite exécuter une requête avec la même URL en accédant toujours aux services WCF (par exemple augmenter le volume qui doit se faire à chaque appel).

Certains contournent ce problème en greffant à l'URL de base un n aléatoire ou un guid. Je n'aime pas particulièrement cette manière de faire et je lui préfère donc un requêtage HTTP / POST qui n'a pas cette problématique de cache du navigateur.

Vous noterez aussi sur le service de récupération du guide (« GetGuide ») deux choses importantes :
  • D'un point de vue objet au niveau de l'interface, j'ai défini deux surcharges de la méthode « GetGuide », ce qui n'est pas possible d'un point de vue contrat de service, d'où l'attribut « OperationContract » paramétré avec un renommage (« GetGuideByDate ») du service visible des clients
  • Le format de la réponse est paramétré au niveau de l'attribut « WebInvoke » en XML. J'aurai tout aussi bien pu utiliser un formatage de type JSON
 
» Démarrer une discussion