Hayadi's Blog

vendredi, février 03, 2006

Services Web ASP.NET ou .NET Remoting ?

Au fil du temps, il est devenu courant de construire des applications sous forme d''ensembles de composants distribués sur un réseau de machines, qui fonctionnent ensemble comme autant d''éléments d''un programme global. Lorsqu''il s''agissait d''applications distribuées, on avait l''habitude d''utiliser des technologies orientées objet ou composant comme DCOM (Distributed Component Object Model, Microsoft®), CORBA (Common Object Request Broker Architecture, Object Management Group) ou RMI (Remote Method Invocation, Sun).
Présentation
Ces technologies offraient une architecture fiable et évolutive qui permettait de répondre aux besoins croissants des applications.
Si ces technologies à composants fonctionnent très bien dans un environnement intranet, leur utilisation sur Internet présente deux problèmes majeurs. Tout d''abord, elles ne sont pas compatibles. Bien qu''elles fonctionnent toutes avec des objets, ces technologies ne s''accordent pas sur les détails, comme par exemple la gestion du cycle de vie, la prise en charge de constructeurs et le degré de prise en charge de l''héritage. Ensuite, et surtout, elles utilisent exclusivement des communications de type RPC, ce qui conduit à des systèmes étroitement imbriqués construits autour d''appels explicites des méthodes objet.
Les applications Web fonctionnant sur navigateur sont, tout au contraire, flexibles et remarquablement interopérables. Elles communiquent via HTTP pour échanger des données MIME dans des formats divers et variés. Les Web Services adaptent le modèle traditionnel de programmation Web pour qu''il soit utilisable dans tous types d''applications et non exclusivement dans celles fonctionnant sur navigateur. Ils échangent des messages SOAP à l''aide de HTTP et autres protocoles Internet. Les Web Services sont fondés sur des normes comme HTTP, XML, SOAP et WSDL ; pour exposer les fonctionnalités d''une application sur Internet, ils sont donc indépendants du langage de programmation, de la plate-forme et du dispositif utilisés.
L''infrastructure des Web Services ASP.NET offre une API simple pour les Web Services, qui fonctionne par mappage de messages SOAP sur des appels de méthodes. Pour ce faire, elle propose un modèle de programmation très simple, qui consiste à mapper les échanges de messages SOAP sur des appels de méthodes spécifiques. Les clients des Web Services ASP.NET n''ont besoin de connaître ni la plate-forme, ni le modèle objet, ni le langage de programmation utilisé pour les construire. Les services eux-mêmes n''ont pas besoin d''avoir d''informations sur les clients qui leur envoient des messages. La seule exigence est que les deux parties s''accordent sur le format des messages SOAP produits et consommés, défini dans le contrat du service Web exprimé à l''aide de WSDL et du schéma XML (XSD).
.NET Remoting offre une infrastructure pour les objets distribués. Il expose l''intégralité de la sémantique objet de .NET aux processus distants par des mécanismes à la fois très flexibles et très extensibles. Par rapport aux Web Services ASP.NET, qui proposent un modèle de programmation très simple basé sur la transmission de messages, .NET Remoting offre des fonctionnalités plus complexes : il prend en charge la transmission d''objets par valeur ou par référence, les rappels, ainsi que des stratégies de gestion des cycles de vie et d''activation de plusieurs objets. Pour utiliser .NET Remoting, un client doit connaître tous ces détails (en fait, le client doit avoir été construit avec .NET ou avec une autre structure prenant en charge .NET Remoting ; la seule que nous connaissions est Ja.NET pour Java, d''Intrinsyc). Les mécanismes de .NET Remoting prennent aussi en charge les messages SOAP, mais il est important de souligner que cela ne change rien à la configuration requise pour le client. Si un point d''entrée distant expose une sémantique objet spécifique à .NET, que ce soit ou non via SOAP, le client doit la comprendre.
Le fait que .NET Framework prenne en charge deux modèles de programmation distribuée différents (Web Services et objets distribués) a créé une certaine confusion pour les développeurs. Comment savoir si un système doit utiliser les Web Services ASP.NET ou .NET Remoting ? Pour répondre à cette question, il faut comprendre comment fonctionnent réellement ces deux technologies.
Sérialisation et métadonnéesEn fin de compte, un mécanisme de communication distribuée effectue deux opérations : il assure le marshaling des instances des types de données de programmation dans des messages pouvant être envoyés sur le réseau et donne une description de l''apparence de ces messages. La première opération est effectuée par un moteur de sérialisation ou marshaler. La deuxième est réalisée au moyen de métadonnées. Par exemple, pour la plupart des interfaces DCOM (jusqu''à présent), le moteur de sérialisation était le Type Library Marshaler et les bibliothèques de types fournissaient les métadonnées. La différence essentielle entre les Web Services ASP.NET et .NET Remoting réside dans la méthode de sérialisation des données en messages et le format utilisé pour les métadonnées.
Services Web ASP.NET, XmlSerializer et XSDLes Web Services ASP.NET utilisent la classe System.Xml.Serialization.XmlSerializer pour effectuer, au moment de l''exécution, le marshaling des données provenant de messages SOAP ou à destination de ceux-ci. Pour les métadonnées, ils génèrent des définitions WSDL et XSD qui décrivent le contenu de leurs messages. Grâce à ce recours exclusif à WSDL et XSD, les métadonnées des Web Services ASP.NET sont portables ; les structures de données sont exprimées de façon à être comprises par d''autres boîtes à outils de Web Services, sur des plates-formes différentes et même avec d''autres modèles de programmation. Dans certains cas, cela impose des contraintes sur les types que vous pouvez exposer à partir d''un service Web (XmlSerializer n''effectue un marshaling que pour les informations qui peuvent être exprimées en XSD). Pour être plus précis, XmlSerializer n''effectue pas de marshaling sur les graphiques d''objets et ne prend ne charge que certains types de conteneurs.
Bien que ces limitations semblent significatives dans une perspective d''objets distribués classique, elles améliorent l''interopérabilité avec d''autres structures de Web Services (objectif essentiel pour un modèle de service Web flexible). L''interopérabilité est encore améliorée par une grande variété d''attributs personnalisés qui permettent d''annoter les types de données afin de contrôler la façon dont le XmlSerializer en assure le marshaling. Vous gardez donc un contrôle précis sur la forme du XML généré lorsqu''un objet est sérialisé. De plus, un service Web basé sur ASP.NET peut être modelé afin de décrire ses messages en termes de XSD littéral ou en fonction des règles de codage de SOAP (c''est-à-dire la section 5 des spécifications de SOAP). Le XSD littéral est défini par défaut et sera dorénavant la norme en vigueur. La prise en charge du codage SOAP est incluse pour conserver une bonne interopérabilité avec les boîtes à outils existantes. Cela s''avère utile, en particulier si vous avez besoin de communiquer avec un client ou un service Web qui ne sait communiquer qu''avec un format de message prédéfini.
.NET Remoting, IFormatter et CLR (Common Language Runtime).NET Remoting a recours aux implémentations connectables de l''interface IFormatter qu''utilise le moteur System.Runtime.Serialization pour effectuer le marshaling des données à destination des messages et en provenance de ceux-ci. Il existe deux formateurs standard : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter et System.Runtime.Serialization.Formatters.Soap.SoapFormatter. Comme leur nom le suggère, BinaryFormatter et SoapFormatter effectuent un marshaling des types en formats binaire et SOAP, respectivement. Pour les métadonnées, .NET Remoting utilise les assemblys du CLR, qui contiennent toutes les informations pertinentes sur les types de données qu''ils mettent en œuvre et les exposent par réflexion. Grâce à l''utilisation d''assemblys pour les métadonnées, il est aisé de préserver une fidélité type-système absolue lors de l''exécution. Ainsi, lorsque les mécanismes de .NET Remoting effectuent un marshaling des données, ils incluent tous les membres d''une classe (publics et privés), gèrent les graphiques d''objet correctement et prennent en charge tous les types de conteneurs (par exemple System.Collections.Hashtable). Toutefois, le recours aux métadonnées d''exécution limite également la portée d''un système .NET Remoting (un client doit comprendre les constructions .NET pour communiquer avec un point d''entrée .NET Remoting). Outre les formateurs connectables, la couche .NET Remoting prend en charge les canaux connectables, qui font abstraction des détails de transmission des messages. Il existe deux canaux standard, un pour le TCP brut et l''autre pour HTTP. Les messages peuvent être envoyés indifféremment sur l''un ou l''autre des canaux, quel que soit leur format.
Jeter le trouble : Remoting et Web ServicesLa présence d''un formateur SOAP et d''un canal HTTP nous amène naturellement à nous poser la question suivante : est-il possible d''utiliser .NET Remoting pour construire des Web Services ? La réponse est oui et non. La pile de technologies standard des Web Services a non seulement recours à des messages SOAP mais aussi à des descriptions WSDL et XSD de ces messages. Remoting peut effectivement générer des définitions WSDL décrivant les messages qu''un point d''entrée produit et consomme. Mais si vous suivez cette logique, vous rencontrerez plusieurs écueils.
Premièrement, les fichiers WSDL générés décrivent toujours les messages selon les règles de codage SOAP et non en XSD littéral. Ce n''est pas un problème dans l''immédiat, mais cela pourrait le devenir lorsque de plus en plus d''outils seront entièrement spécifiques à des schémas.
Deuxièmement, les fichiers WSDL générés comportent des extensions spécifiques à .NET Remoting. Par exemple, voici une classe simple qui utilise .NET Remoting pour exposer son comportement.
public class Methods : MarshalByRefObject { // La méthode Now renvoie l''heure et la date en cours public string Now() { return System.DateTime.Now.ToString(); } } Si vous générez du WSDL à partir de cette classe, les informations de liaison comprendront des détails spécifiques à .NET Remoting, comme montré ci-dessous.
... ... Ces éléments supplémentaires sont autorisés car les spécifications WSDL prennent en charge l''extensibilité. Si elle est bien conçue, une boîte à outils de service Web qui ne les comprendrait pas doit simplement les ignorer. Il existe cependant quelques éléments qu''une boîte à outils de service ne peut ignorer. Par exemple, voici un point d''entrée distant qui renvoie un System.Data.DataSet Microsoft® ADO.NET.
public class Methods : MarshalByRefObject { public System.Data.DataSet GetEmptyDataSet() { return new System.Data.DataSet(); } } Voici la définition WSDL générée pour le message résultant de cette méthode :
Normalement, un message WSDL fait référence aux types définis dans un espace de nom spécifique à l''aide du schéma XML. Dans ce cas néanmoins, le préfixe d''espace de noms ns3 appliqué au type DataSet n''est pas défini en XSD. Il est défini implicitement via l''exécution. Dans cet exemple, le préfixe ns3 est lié à un espace de noms XML identifié par cette URL :
http://schemas.microsoft.com/clr/nsassem/System.Data/System.Data%2C%20Version%3D1.0.3300.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Db77a5c561934e089
Les consommateurs de cette définition WSDL sont censés comprendre la signification particulière de cette URL « bien connue » (il s''agit du nom fort en quatre parties d''un assembly d''exécution spécifique compris dans .NET Framework). Ce style de WSDL est idéal pour les clients mis en œuvre avec .NET Remoting car ils peuvent générer un assembly proxy contenant les informations adéquates pour le marshaling. Cependant, pour les boîtes à outils d''autres Web Services (ASP.NET notamment) qui ne comprennent pas cette URL et s''attendent à trouver une définition de schéma pour le type DataSet, ce WSDL sera inutile.
La question reste donc posée : peut-on utiliser .NET Remoting pour construire des Web Services ? Oui, au sens strict du terme, c''est possible. Mais ceux qui n''utilisent pas les mécanismes de .NET Remoting seront-ils capables de les exploiter ? Peut-être, si vous prenez soin de restreindre votre point d''entrée à un minimum de types de données et de sémantique. Plus précisément, si vous souhaitez mettre en place une bonne interopérabilité avec les boîtes à outils d''autres Web Services, vous devez restreindre les paramètres aux types simples prédéfinis et à vos propres types de données (n''utilisez pas les types .NET Framework comme DataSet) et éviter les événements et les objets activés par les clients. En bref, si la portée est pour vous une question importante, vous devez vous restreindre aux fonctionnalités que les Web Services ASP.NET prennent en charge.
Mieux encore, utilisez les Web Services ASP.NET, c''est exactement pour cela qu''ils sont conçus.