Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
La première étape de l’écriture d’un transport personnalisé consiste à décider quels modèles d’échange de messages (ou députés ) sont requis pour le canal que vous développez. Cette rubrique décrit les options disponibles et décrit les différentes exigences. Il s’agit de la première tâche de la liste des tâches de développement de canal décrite dans Développement de canaux.
Six modèles d’échange de messages
Il existe trois députés parmi lesquels choisir :
Datagram (IInputChannel et IOutputChannel)
Lorsque vous utilisez un MEP datagramme, un client envoie un message en utilisant un échange de type déclencher et oublier (fire and forget). Un échange de ce type requiert une confirmation hors bande de la réussite de la remise. Le message peut être perdu en transit et n’atteindre jamais le service. Si l’opération d’envoi se termine correctement du côté du client, cela ne garantit pas que le récepteur distant ait reçu le message. Le datagramme est un bloc de construction fondamental pour la messagerie, car vous pouvez créer vos propres protocoles, y compris des protocoles fiables et des protocoles sécurisés. Les canaux de datagramme client implémentent l'interface IOutputChannel et les canaux de datagramme de service implémentent l’interface IInputChannel.
Request-Response (IRequestChannel et IReplyChannel)
Dans ce MEP, un message est envoyé et une réponse est reçue. Le modèle se compose de paires demande-réponse. Des exemples d’appels de demande-réponse sont des appels de procédure distante (RPC) et des requêtes GET du navigateur. Ce modèle est également appelé demi-duplex. Dans ce MEP, les canaux clients implémentent IRequestChannel et les canaux de service implémentent IReplyChannel.
Duplex (IDuplexChannel)
Le MEP duplex permet à un client d'envoyer un nombre arbitraire de messages et de les recevoir dans n’importe quel ordre. Le MEP duplex est similaire à une conversation téléphonique, où chaque mot prononcé correspond à un message. Étant donné que les deux côtés peuvent envoyer et recevoir dans ce MEP, l’interface implémentée par le client et les canaux de service est IDuplexChannel.
Les trois modèles d’échange de messages de base. De haut en bas : datagramme, demande-réponse et duplex.
Chacun de ces députés peut également prendre en charge des sessions. Une session (et une implémentation de System.ServiceModel.Channels.ISessionChannel<TSession> de type System.ServiceModel.Channels.ISession) met en corrélation tous les messages envoyés et reçus sur un canal. Le modèle demande-réponse est une session à deux messages autonome, car la demande et la réponse sont corrélées. En revanche, le modèle de demande-réponse qui prend en charge les sessions implique que toutes les paires demande/réponse sur ce canal sont corrélées les unes avec les autres. Cela vous donne un total de six députés parmi lesquels choisir :
Datagramme
Demande-réponse
Duplex
Datagramme avec des sessions
Demande-réponse avec sessions
Duplex avec sessions
Remarque
Pour le transport UDP, le seul MEP pris en charge est datagramme, le protocole UDP, de part sa nature même, permettant uniquement l'échange de messages de type « déclenché et oublié ».
Sessions et canaux de session
Dans le monde du réseau, il existe des protocoles orientés connexion (par exemple, TCP) et des protocoles sans connexion (par exemple, UDP). WCF utilise le terme session pour désigner une abstraction logique de type connexion. Les protocoles WCF avec session sont similaires aux protocoles réseau orientés connexion et les protocoles WCF sans session sont similaires aux protocoles réseau sans connexion.
Dans le modèle objet de canal, chaque session logique se manifeste comme une instance d’un canal comportant une session. Par conséquent, chaque nouvelle session créée par le client et acceptée sur le service correspond à un nouveau canal avec session de chaque côté. Le diagramme suivant montre, en haut, la structure des canaux sans session et, en bas, la structure des canaux avec session.
Un client crée un canal avec session et envoie un message. Côté service, l’écouteur de canal reçoit ce message et détecte qu’il appartient à une nouvelle session afin qu’il crée un canal avec session et le remet à l’application (en réponse à l’application appelant AcceptChannel sur l’écouteur de canal). L’application reçoit ensuite ce message et tous les messages suivants envoyés dans la même session via le même canal de session.
Un autre client (ou le même client) crée un nouveau sessionful et envoie un message. L'écouteur de canal détecte que ce message figure dans une nouvelle session et crée un nouveau canal de session, puis la même procédure se répète.
Sans sessions, il n’existe aucune corrélation entre les canaux et les sessions. Par conséquent, un écouteur de canal crée un seul canal via lequel tous les messages reçus sont remis à l’application. Il n’existe pas non plus d’ordre de message, car il n’y a pas de session dans laquelle maintenir l’ordre des messages. La partie supérieure du graphique précédent illustre un échange de messages sans session.
Démarrage et fin des sessions
Les sessions sont démarrées à partir du client à la création par ce dernier d'un nouveau canal de session. Elles sont démarrées à partir du service à réception par cette dernière d'un message envoyé dans une nouvelle session. De même, les sessions sont arrêtées en fermant ou en abandonnant un canal avec session.
L’exception à ceci est IDuplexSessionChannel utilisée pour l’envoi et la réception de messages dans un modèle de communication duplex avec session. Il est possible qu’un côté souhaite arrêter l’envoi de messages tout en continuant à en recevoir. Par conséquent, en utilisant IDuplexSessionChannel, il existe un mécanisme qui vous permet de fermer la session de sortie pour indiquer que vous n’enverrez plus de messages tout en gardant la session d’entrée ouverte, ce qui vous permet de continuer à recevoir des messages.
En général, les sessions sont fermées du côté sortant et non du côté entrant. En d'autres termes, il est possible de fermer les canaux de sortie des sessions, permettant ainsi de mettre correctement un terme à ces dernières. Lorsqu'un canal de sortie de session est fermé, le canal d'entrée de session retourne la valeur null en réponse à l'appel IInputChannel.Receive de l'application sur IDuplexSessionChannel.
Toutefois, les canaux d’entrée avec session ne doivent pas être fermés, sauf si IInputChannel.Receive sur IDuplexSessionChannel renvoie la valeur null, signifiant que la session est déjà fermée. Lorsque la méthode IInputChannel.Receive sur IDuplexSessionChannel ne retourne pas la valeur null, la fermeture du canal d'entrée de session risque de lever une exception, celui-ci étant susceptible de recevoir des messages de manière inopinée pendant le processus de fermeture. Si un récepteur souhaite mettre fin à une session avant que l’expéditeur ne le fasse, il doit appeler Abort le canal d’entrée, ce qui met brusquement fin à la session.
Création des canaux de session
Lorsque vous créez des canaux de session, ceux-ci doivent remplir certaines conditions pour permettre l'avènement des sessions. Côté envoi, votre canal doit :
Pour chaque nouveau canal, créez une nouvelle session et associez-la à un nouvel ID de session qui est une chaîne de caractères unique. Ou obtenir une nouvelle session à partir du canal de session figurant en dessous du vôtre dans la pile.
Pour chaque message envoyé à l’aide de ce canal, si votre canal a créé la session (par opposition à l’obtenir à partir de la couche ci-dessous), vous devez associer le message à la session. Pour les canaux de protocole, cela est généralement effectué en ajoutant un en-tête SOAP. Pour les canaux de transport, cela est généralement effectué en créant une connexion de transport ou en ajoutant des informations de session au protocole d’encadrement.
Pour chaque message envoyé à l’aide de ce canal, vous devez fournir les garanties de remise mentionnées ci-dessus. Si vous vous appuyez sur le canal ci-dessous pour fournir la session, ce canal fournira également les garanties de livraison. Si vous fournissez vous-même la session, vous devez implémenter ces garanties dans le cadre de votre protocole. En général, si vous écrivez un canal de protocole qui suppose WCF des deux côtés, vous pouvez exiger le transport TCP ou le canal de messagerie fiable et s’appuyer sur l’un ou l’autre pour fournir une session.
Lorsque la méthode ICommunicationObject.Close est appelée sur votre canal, effectuez la tâche requise pour fermer la session en utilisant le délai spécifié ou le délai par défaut. Cela peut être aussi simple que d’appeler Close sur le canal ci-dessous (si vous venez d’obtenir la session à partir de celui-ci) ou d’envoyer un message SOAP spécial ou de fermer une connexion de transport.
Quand Abort est appelée sur votre canal, terminez la session brutalement sans effectuer d’entrées/sorties. Cela peut signifier ne rien faire ou impliquer l’abandon d’une connexion réseau ou d’une autre ressource.
Côté réception, votre canal doit :
Pour chaque message entrant, l’écouteur de canal doit détecter la session à laquelle elle appartient. S'il s'agit du premier message dans la session, l'écouteur de canal doit créer un nouveau canal et le retourner en réponse à l'appel de la méthode IChannelListener<TChannel>.AcceptChannel. Sinon, l’écouteur de canal doit rechercher le canal existant qui correspond à la session et remettre le message via ce canal.
Si votre canal fournit la session (ainsi que les garanties de remise requises), il peut être nécessaire pour le côté réception d'effectuer certaines actions telles que réorganiser les messages ou envoyer des accusés de réception.
Lorsque la méthode Close est appelée sur votre canal, opérez la tâche requise pour fermer la session en utilisant le délai spécifié ou le délai par défaut. Cette opération peut provoquer la levée d'une exception si le canal reçoit un message avant expiration du délai de fermeture. Ce qui est prévisible dans la mesure où l'état du canal est « en cours de fermeture » lorsqu'il reçoit le message.
Quand Abort est appelée sur votre canal, terminez la session brutalement sans effectuer d’entrées/sorties. Là encore, cela peut signifier ne rien faire ou peut impliquer l’abandon d’une connexion réseau ou d’une autre ressource.