Codeurs personnalisés
Cette rubrique décrit comment créer des codeurs personnalisés.
Dans Windows Communication Foundation (WCF), les liaisons permettent de spécifier comment transférer des données sur un réseau entre des points de terminaison. Une liaison est composée d'une séquence d'éléments de liaison. Une liaison inclut des éléments de liaison de protocole facultatifs, tels que la sécurité, un élément de liaison de codeur de message et un élément de liaison de transport requis. Un codeur de message est représenté par un élément de liaison de codage de message. Trois codeurs de message sont inclus dans WCF : Binary, MTOM (Message Transmission Optimization Mechanism) et Text.
Un élément de liaison de codage de message sérialise un Message sortant et le passe au transport ou reçoit la forme sérialisée d'un message du transport et le transmet à la couche de protocole (si celle-ci est présente), ou à l'application (dans le cas contraire).
Les codeurs de message transforment des instances Message vers une représentation sur le câble ou à partir de celle-ci. Même si les codeurs sont décrits comme étant situés au-dessus de la couche de transport dans la pile des canaux, ils résident en fait à l'intérieur de cette couche. Les transports (par exemple HTTP) mettent en forme le message selon les spécifications de la norme de transport. Les codeurs (par exemple Text Xml) se contentent de coder le message.
Lorsque vous vous connectez à un client ou à un serveur préexistant, vous n'aurez peut-être pas le choix de l'utilisation d'un codage de message particulier. Toutefois, les services WCF peuvent être accessibles par l'intermédiaire de plusieurs points de terminaison, chacun ayant un codeur de message différent. Lorsqu'un codeur unique ne couvre pas toute l'audience de votre service, vous pouvez exposer votre service sur plusieurs points de terminaison. Les applications clientes peuvent utiliser ensuite le point de terminaison le mieux adapté. L'utilisation de plusieurs points de terminaison vous permet de combiner les avantages des codeurs de message différents avec d'autres éléments de liaison.
Codeurs fournis par le système
WCF fournit plusieurs liaisons fournies par le système et conçues pour couvrir les scénarios d'application les plus courants. Chacune de ces liaisons associe un transport, un codeur de message et d'autres options (la sécurité, par exemple). Cette rubrique décrit comment étendre les codeurs de message Text, Binary et MTOM inclus dans WCF, ou comment créer votre propre codeur personnalisé. Le codeur de message texte prend en charge un codage XML ordinaire ainsi que des codages SOAP. Le mode de codage XML brut du codeur de message texte est appelé POX (Plain Old XML) afin de le distinguer du codage SOAP basé sur le texte.
Pour plus d'informations sur les combinaisons d'éléments de liaison associées aux liaisons fournies par le système, consultez la section correspondante dans Choix d'un transport.
Comment utiliser des codeurs fournis par le système
Un codage est ajouté à une liaison à l'aide d'une classe dérivée de MessageEncodingBindingElement.
WCF fournit les types suivants d'éléments de liaison dérivés de la classe MessageEncodingBindingElement qui peut fournir le codage Text, Binary et MTOM :
- TextMessageEncodingBindingElement est le codeur le plus interopérable, mais le moins efficace pour les messages XML. Un service Web ou un client de service Web comprend généralement le XML textuel. Toutefois, transmettre de larges blocs de données binaires sous la forme de texte n'est pas efficace.
- BinaryMessageEncodingBindingElement représente l'élément de liaison qui spécifie le codage de caractères et le versioning de messages utilisés pour les messages XML binaires. Il s'agit de la plus efficace des options de codage, mais la moins interopérable, parce qu'elle est prise en charge uniquement par les points de terminaison WCF.
- MTOMMessageEncodingBindingElement : représente l'élément de liaison qui spécifie le codage de caractères et le versioning de messages utilisés pour un message qui utilise un codage MTOM. MTOM est une technologie efficace pour la transmission de données binaires dans les messages WCF. Le codeur MTOM tente de parvenir à un équilibre entre rendement et interopérabilité. Le codage MTOM transmet la plupart du XML sous forme textuelle, mais optimise les blocs de données binaires volumineux en les transmettant tels quels, sans conversion en texte.
L'élément de liaison crée un MessageEncoderFactory Binary, MTOM ou Text. La fabrique crée une instance MessageEncoder Binary, MTOM ou Text. En général, il n'y a qu'une instance unique. Toutefois si des sessions sont utilisées, un codeur différent peut être fourni à chaque session. Le codeur Binary utilise celle-ci pour coordonner des dictionnaires dynamiques (consultez Infrastructure XML).
Les méthodes ReadMessage et WriteMessage sont les éléments principaux des codeurs. Les méthodes permettent de lire un message d'un flux de données ou d'un tableau Byte. Les tableaux d'octets sont utilisés lorsque le transport fonctionne en mode mémoire tampon. Les messages sont toujours écrits dans des flux de données. Si le transport doit mettre le message en mémoire tampon, il fournit un flux de données qui effectue la mise en mémoire tampon.
Le reste des membres utilisent le contenu de support, les types de média et MessageVersion. Le transport appelle ces méthodes de codeur pour tester s'il peut décoder le message entrant ou pour déterminer si le message sortant est valide pour cet encodeur.
Chacune des trois implémentations de codeur ajoute des propriétés qui sont pertinentes aux codages spécifiques et sont entièrement configurables. Les codeurs exposent aussi des quotas de lecteur qui ont des valeurs sécurisées par défaut. Consultez Infrastructure XML pour une description des quotas.
Fonctionnalités des codeurs fournis par le système
Les codeurs fournis par le système offrent plusieurs fonctionnalités.
Regroupement
Chacune des implémentations de codeur essaient de regrouper autant que possible. La réduction d'allocations est un moyen clé pour améliorer les performances du code managé. Pour accomplir ce regroupement, les implémentations utilisent la classe SynchronizedPool. Le fichier C# contient une description des optimisations supplémentaires utilisées par cette classe.
Les instances XmlDictionaryReader et XmlDictionaryWriter sont regroupées et réinitialisées pour empêcher d'en allouer des nouvelles pour chaque message. Pour les lecteurs, un rappel OnClose récupère le lecteur lorsque Close() est appelé. Le codeur recycle aussi certains objets de l'état du message utilisés pour construire des messages. Les tailles de ces regroupements sont configurables par les propriétés MaxReadPoolSize et MaxWritePoolSize sur chacune des trois classes dérivées de MessageEncodingBindingElement.
Codage Binaire
Lorsque le codage binaire utilise des sessions, la chaîne de dictionnaire dynamique doit être communiquée au récepteur du message. Cette opération s'effectue en préfixant le message avec les chaînes de dictionnaire dynamiques. Le récepteur supprime des chaînes, les ajoute à la session et traite le message. La transmission correcte des chaînes de dictionnaire nécessite la mise en mémoire tampon du transport.
Les chaînes sont ajoutées au message par une méthode AddSessionInformationToMessage interne. Elle ajoute les chaînes au format UTF-8 au début du message précédées de leur longueur. Puis l'en-tête entier de dictionnaire est préfixé avec la longueur de ses données. L'opération inverse est effectuée par une méthode interne ExtractSessionInformationFromMessage.
En plus de traiter des clés de dictionnaire dynamiques, les messages de session en mémoire tampon sont reçus d'une manière unique. Au lieu de créer un lecteur sur le document et de le traiter, le codeur binaire utilise la classe interne MessagePatterns pour déconstruire le flux binaire. L'idée est que la plupart des messages possède un certain jeu d'en-têtes qui apparaissent dans un certain ordre lorsqu'ils sont générés par WCF. Le système de modèle décompose le message en fonction de ce qu'il en attend. Si l'opération aboutie, il initialise un objet MessageHeaders sans analyser le XML. Dans le cas contraire, il revient à la méthode standard.
Codage MTOM
La classe MtomMessageEncodingBindingElement a une propriété de configuration supplémentaire appelée MaxBufferSize. Celle-ci place une limite supérieure sur la quantité de données qu'il est possible de mettre en mémoire tampon pendant la lecture d'un message. Le jeu d'informations XML (Infoset), ou d'autres parties MIME, peuvent nécessiter leur mise en mémoire tampon pour réassembler toutes les parties MIME dans un message unique.
Pour fonctionner correctement avec HTTP, la classe de codeur de message MTOM interne fournit des API internes pour GetContentType (qui est aussi interne) et WriteMessage qui est public et peut être substitué. Il doit s'effectuer plus de communication pour que les valeurs dans les en-têtes HTTP soient conformes aux valeurs dans les en-têtes MIME.
En interne, le codeur de message MTOM utilise les lecteurs de texte de WCF, il est semblable au codeur Text. La différence principale est qu'il optimise des segments importants de binaire, ou BLOB (Binary Large Objects) en ne les convertissant pas en codage de base 64 avant d'être incorporé dans les octets de message. À la place, ces BLOB restent extraits et référencés comme des pièces jointes MIME.
Écriture de votre propre codeur
Pour implémenter votre propre codeur de message personnalisé, vous devez fournir des implémentations personnalisées des classes de base abstraites suivantes :
- MessageEncoder
- MessageEncoderFactory
- MessageEncodingBindingElement
La conversion de la représentation en mémoire d'un message en une représentation qui peut être écrite dans un flux de données est encapsulée dans la classe MessageEncoder qui agit en tant que fabrique pour les lecteurs XML et writers XML qui prennent en charge des types spécifiques de codages XML.
- Les méthodes clés de cette classe que vous devez substituer sont :
- WriteMessage qui accepte un objet Message et l'écrit dans un objet Stream.
- ReadMessage qui accepte un objet Stream et une taille d'en-tête maximale et retourne un objet Message.
C'est le code que vous écrivez dans ces méthodes qui gèrent la conversion entre le protocole de transport standard, et votre codage personnalisé.
Ensuite, vous devez coder une classe de fabrique qui crée votre codeur personnalisé. Substituez Encoder pour retourner une instance de votre MessageEncoder personnalisé.
Puis connectez votre MessageEncoderFactory personnalisé à la pile d'élément de liaison utilisée pour configurer le service ou le client en substituant la méthode CreateMessageEncoderFactory pour retourner une instance de cette fabrique.
Deux exemples fournis avec WCF illustrent ce processus à l'aide d'un exemple de code : Custom Message Encoder: Custom Text Encoder et Custom Message Encoder: Compression Encoder.
Voir aussi
Référence
MessageEncodingBindingElement
MessageEncoderFactory
MessageEncoder
Concepts
Vue d'ensemble de l'architecture de transfert de données
Sélection d'un codeur de message
Choix d'un transport