Partage via


Présentation du routage

Le service de routage fournit un intermédiaire SOAP enfichable générique capable de router les messages en fonction du contenu du message. Avec le service de routage, vous pouvez créer une logique de routage complexe qui vous permet d’implémenter des scénarios tels que l’agrégation de service, le contrôle de version de service, le routage prioritaire et le routage multidiffusion. Le service de routage fournit également une gestion des erreurs qui vous permet de configurer des listes de points de terminaison de sauvegarde auxquels les messages sont envoyés en cas d’échec lors de l’envoi au point de terminaison de destination principal.

Cette rubrique est destinée aux personnes nouvelles du service de routage et couvre la configuration de base et l’hébergement du service de routage.

Paramétrage

Le service de routage est implémenté en tant que service WCF qui expose un ou plusieurs points de terminaison de service qui reçoivent des messages des applications clientes et routent les messages vers un ou plusieurs points de terminaison de destination. Le service fournit une classe RoutingBehavior, appliquée aux points de terminaison de service exposés par le service. Ce comportement est utilisé pour configurer différents aspects du fonctionnement du service. Pour faciliter la configuration lors de l’utilisation d’un fichier de configuration, les paramètres sont spécifiés sur RoutingBehavior. Dans les scénarios basés sur le code, ces paramètres sont spécifiés dans le cadre d’un RoutingConfiguration objet, qui peut ensuite être transmis à un RoutingBehavior.

Au démarrage, ce comportement ajoute le SoapProcessingBehavior, qui est utilisé pour effectuer le traitement SOAP des messages, aux points de terminaison clients. Cela permet au service de routage de transmettre des messages aux points de terminaison qui nécessitent un MessageVersion différent du point de terminaison sur lequel le message a été reçu. RoutingBehavior inscrit également une extension de service, qui RoutingExtensionfournit un point d’accessibilité pour modifier la configuration du service de routage au moment de l’exécution.

La classe RoutingConfiguration fournit un moyen cohérent de configurer et de mettre à jour la configuration du service de routage. Il contient des paramètres qui agissent comme paramètres pour le service de routage et sont utilisés pour configurer RoutingBehavior au démarrage du service, ou qui sont passés à RoutingExtension pour modifier la configuration du routage au moment de l’exécution.

La logique de routage utilisée pour effectuer le routage basé sur le contenu des messages est définie en regroupant plusieurs MessageFilter objets dans des tables de filtre (MessageFilterTable<TFilterData> objets). Les messages entrants sont évalués par rapport aux filtres de messages contenus dans la table de filtres, et pour chaque MessageFilter qui correspond au message, transféré vers un point de terminaison de destination. La table de filtre qui doit être utilisée pour router les messages est spécifiée à l’aide de RoutingBehavior dans la configuration ou via du code à l’aide de l’objet RoutingConfiguration .

Définition de points de terminaison

Bien qu’il semble que vous deviez démarrer votre configuration en définissant la logique de routage que vous utiliserez, votre première étape doit réellement être de déterminer la forme des points de terminaison vers lesquels vous dirigerez les messages. Le service de routage utilise des contrats qui définissent la forme des canaux utilisés pour recevoir et envoyer des messages. Par conséquent, la forme du canal d’entrée doit correspondre à celle du canal de sortie. Par exemple, si vous effectuez un routage vers des points de terminaison qui utilisent la forme du canal de demande-réponse, vous devez utiliser un contrat compatible sur les points de terminaison entrants, tels que le IRequestReplyRouter.

Cela signifie que si vos points de terminaison de destination utilisent des contrats avec plusieurs modèles de communication (tels que la combinaison d’opérations unidirectionnelles et bidirectionnelles), vous ne pouvez pas créer un point de terminaison de service unique qui peut recevoir et router les messages vers tous ces derniers. Vous devez déterminer quels points de terminaison ont des formes compatibles et définir un ou plusieurs points de terminaison de service qui seront utilisés pour recevoir des messages à router vers les points de terminaison de destination.

Remarque

Lorsque vous travaillez avec des contrats qui spécifient plusieurs modèles de communication (par exemple, une combinaison d’opérations unidirectionnelles et bidirectionnelles), une solution de contournement consiste à utiliser un contrat duplex au niveau du service de routage tel que IDuplexSessionRouter. Toutefois, cela signifie que la liaison doit être capable de communiquer en duplex, ce qui peut ne pas être possible pour tous les scénarios. Dans les scénarios où cela n’est pas possible, la prise en compte de la communication dans plusieurs points de terminaison ou la modification de l’application peut être nécessaire.

Pour plus d’informations sur les contrats de routage, consultez Contrats de Routage.

Une fois le point de terminaison de service défini, vous pouvez utiliser RoutingBehavior pour associer un RoutingConfiguration spécifique au point de terminaison. Lors de la configuration du service de routage à l’aide d’un fichier de configuration, RoutingBehavior est utilisé pour spécifier la table de filtres qui contient la logique de routage utilisée pour traiter les messages reçus sur ce point de terminaison. Si vous configurez le service de routage par programmation, vous pouvez spécifier la table de filtres à l’aide de RoutingConfiguration.

L’exemple suivant définit les points de terminaison de service et de client utilisés par le service de routage par programme et à l’aide d’un fichier de configuration.

<services>
  <!--ROUTING SERVICE -->
  <service behaviorConfiguration="routingData"
            name="System.ServiceModel.Routing.RoutingService">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8000/routingservice/router"/>
      </baseAddresses>
    </host>
    <!-- Define the service endpoints that are receive messages -->
    <endpoint address=""
              binding="wsHttpBinding"
              name="reqReplyEndpoint"
              contract="System.ServiceModel.Routing.IRequestReplyRouter" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="routingData">
      <serviceMetadata httpGetEnabled="True"/>
      <!-- Add the RoutingBehavior and specify the Routing Table to use -->
      <routing filterTableName="routingTable1" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<client>
<!-- Define the client endpoint(s) to route messages to -->
  <endpoint name="CalculatorService"
            address="http://localhost:8000/servicemodelsamples/service"
            binding="wsHttpBinding" contract="*" />
</client>
//set up some communication defaults
string clientAddress = "http://localhost:8000/servicemodelsamples/service";
string routerAddress = "http://localhost:8000/routingservice/router";
Binding routerBinding = new WSHttpBinding();
Binding clientBinding = new WSHttpBinding();
//add the endpoint the router uses to receive messages
serviceHost.AddServiceEndpoint(
     typeof(IRequestReplyRouter),
     routerBinding,
     routerAddress);
//create the client endpoint the router routes messages to
ContractDescription contract = ContractDescription.GetContract(
     typeof(IRequestReplyRouter));
ServiceEndpoint client = new ServiceEndpoint(
     contract,
     clientBinding,
     new EndpointAddress(clientAddress));
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
….
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
//attach the behavior to the service host
serviceHost.Description.Behaviors.Add(
     new RoutingBehavior(rc));

Cet exemple configure le service de routage de manière à exposer un point de terminaison unique, avec pour adresse http://localhost:8000/routingservice/router, qui est utilisé pour recevoir les messages à router. Étant donné que les messages sont routés vers des points de terminaison de demande-réponse, le point de terminaison de service utilise le IRequestReplyRouter contrat. Cette configuration définit également un point de terminaison client unique de http://localhost:8000/servicemodelsample/service, vers lequel les messages sont routés. La table de filtres (non affichée) nommée « routingTable1 » contient la logique de routage utilisée pour router les messages et est associée au point de terminaison de service à l’aide du routageBehavior (pour un fichier de configuration) ou routingConfiguration (pour la configuration programmatique).

Logique de routage

Pour définir la logique de routage utilisée pour router les messages, vous devez déterminer les données contenues dans les messages entrants peuvent être utilisées de manière unique. Par exemple, si tous les points de terminaison de destination vers lesquels vous effectuez le routage partagent les mêmes actions SOAP, la valeur de l’action contenue dans le message n’est pas un bon indicateur du point de terminaison spécifique auquel le message doit être acheminé. Si vous devez acheminer de manière unique les messages vers un point de terminaison spécifique, vous devez filtrer les données qui identifient de manière unique le point de terminaison de destination vers lequel le message est acheminé.

Le service de routage fournit plusieurs implémentations MessageFilter qui inspectent des valeurs spécifiques dans le message, telles que l’adresse, l’action, le nom du point de terminaison ou même une requête XPath. Si aucune de ces implémentations ne répond à vos besoins, vous pouvez créer une implémentation MessageFilter personnalisée. Pour plus d’informations sur les filtres de messages et une comparaison des implémentations utilisées par le service de routage, consultez Filtres de messages et Choix d’un filtre.

Plusieurs filtres de messages sont organisés en tables de filtre, qui associent chaque MessageFilter à un point de terminaison de destination. Si vous le souhaitez, la table de filtres peut également être utilisée pour spécifier une liste de points de terminaison de sauvegarde auxquels le service de routage tente d’envoyer le message en cas d’échec de transmission.

Par défaut, tous les filtres de messages d’une table de filtres sont évalués simultanément ; Toutefois, vous pouvez spécifier un Priority qui entraîne l’évaluation des filtres de messages dans un ordre spécifique. Toutes les entrées avec la priorité la plus élevée sont évaluées en premier, et les filtres de messages de priorités inférieures ne sont pas évalués si une correspondance est trouvée à un niveau de priorité supérieur. Pour plus d’informations sur les tables de filtre, consultez Filtres de messages.

Les exemples suivants utilisent le MatchAllMessageFilter, qui est évalué à true pour tous les messages. Ce MessageFilter est ajouté à la table de filtre « routingTable1 », qui associe le MessageFilter au point de terminaison client nommé « CalculatorService ». RoutingBehavior spécifie ensuite que cette table doit être utilisée pour router les messages traités par le point de terminaison de service.

<behaviors>
  <serviceBehaviors>
    <behavior name="routingData">
      <serviceMetadata httpGetEnabled="True"/>
      <!-- Add the RoutingBehavior and specify the Routing Table to use -->
      <routing filterTableName="routingTable1" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<!--ROUTING SECTION -->
<routing>
  <filters>
    <filter name="MatchAllFilter1" filterType="MatchAll" />
  </filters>
  <filterTables>
    <table name="routingTable1">
      <filters>
        <add filterName="MatchAllFilter1" endpointName="CalculatorService" />
      </filters>
    </table>
  </filterTables>
</routing>
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
//create the endpoint list that contains the endpoints to route to
//in this case we have only one
List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
endpointList.Add(client);
//add a MatchAll filter to the Router's filter table
//map it to the endpoint list defined earlier
//when a message matches this filter, it is sent to the endpoint contained in the list
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);

Remarque

Par défaut, le service de routage évalue uniquement les en-têtes du message. Pour autoriser les filtres à accéder au corps du message, vous devez définir RouteOnHeadersOnly sur false.

multidiffusion

Bien que de nombreuses configurations de service de routage utilisent une logique de filtre exclusive qui achemine les messages vers un seul point de terminaison spécifique, vous devrez peut-être acheminer un message donné vers plusieurs points de terminaison de destination. Pour multidiffusion d’un message vers plusieurs destinations, les conditions suivantes doivent être remplies :

  • La forme de canal ne doit pas être demande-réponse (mais peut être unidirectionnel ou duplex), car une seule réponse peut être reçue par l’application cliente en réponse à la demande.

  • Plusieurs filtres doivent retourner true lors de l’évaluation du message.

Si ces conditions sont remplies, le message est routé vers tous les points de terminaison de tous les filtres qui évaluent true. L’exemple suivant définit une configuration de routage qui entraîne l’acheminement des messages vers les deux points de terminaison si l’adresse du point de terminaison dans le message est http://localhost:8000/routingservice/router/rounding.

<!--ROUTING SECTION -->
<routing>
  <filters>
    <filter name="MatchAllFilter1" filterType="MatchAll" />
    <filter name="RoundingFilter1" filterType="EndpointAddress"
            filterData="http://localhost:8000/routingservice/router/rounding" />
  </filters>
  <filterTables>
    <table name="routingTable1">
      <filters>
        <add filterName="MatchAllFilter1" endpointName="CalculatorService" />
        <add filterName="RoundingFilter1" endpointName="RoundingCalcService" />
      </filters>
    </table>
  </filterTables>
</routing>
rc.FilterTable.Add(new MatchAllMessageFilter(), calculatorEndpointList);
rc.FilterTable.Add(new EndpointAddressMessageFilter(new EndpointAddress(
    "http://localhost:8000/routingservice/router/rounding")),
    roundingCalcEndpointList);

Traitement SOAP

Pour prendre en charge le routage des messages entre différents protocoles, le RoutingBehavior ajoute par défaut à SoapProcessingBehavior tous les points de terminaison clients vers lesquels les messages sont routés. Ce comportement crée automatiquement une nouvelle MessageVersion avant de router le message vers le point de terminaison, et génère également une MessageVersion compatible pour tout document de réponse avant de le renvoyer à l'application cliente qui l'a demandé.

Les étapes effectuées pour créer un messageVersion pour le message sortant sont les suivantes :

Traitement des demandes

  • Obtenez le MessageVersion de la liaison sortante ou du canal sortant.

  • Obtenez le lecteur de corps du message d'origine.

  • Créez un message avec la même action, le même lecteur de corps et un nouveau MessageVersion.

  • Si Addressing ! = Addressing.None, copiez les en-têtes To, From, FaultTo, et RelatesTo dans le nouveau message.

  • Copiez toutes les propriétés du message dans le nouveau message.

  • Stockez le message de demande d’origine à utiliser lors du traitement de la réponse.

  • Retourne le nouveau message de demande.

Traitement des réponses

  • Obtenez messageVersion du message de requête d’origine.

  • Obtenez le lecteur de corps du message de réponse reçu.

  • Créez un message de réponse avec la même action, le même lecteur de corps et le MessageVersion du message de demande d'origine.

  • Si Addressing ! = Addressing.None, copiez les en-têtes To, From, FaultTo, et RelatesTo dans le nouveau message.

  • Copiez les propriétés du message dans le nouveau message.

  • Retourne le nouveau message de réponse.

Par défaut, le SoapProcessingBehavior est automatiquement ajouté aux points de terminaison clients lors du démarrage du service RoutingBehavior. Toutefois, vous pouvez contrôler si le traitement SOAP est ajouté à tous les points de terminaison clients en utilisant la propriété SoapProcessingEnabled. Vous pouvez également ajouter le comportement directement à un point de terminaison spécifique et activer ou désactiver ce comportement au niveau du point de terminaison si un contrôle plus précis du traitement SOAP est nécessaire.

Remarque

Si le traitement SOAP est désactivé pour un point de terminaison qui nécessite un MessageVersion différent de celui du message de demande d’origine, vous devez fournir un mécanisme personnalisé pour effectuer les modifications SOAP requises avant d’envoyer le message au point de terminaison de destination.

Dans les exemples suivants, la propriété soapProcessingEnabled est utilisée pour empêcher l’ajout automatique de SoapProcessingBehavior à tous les points de terminaison clients.

<behaviors>
  <!--default routing service behavior definition-->
  <serviceBehaviors>
    <behavior name="routingConfiguration">
      <routing filterTableName="filterTable1" soapProcessingEnabled="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
//create the default RoutingConfiguration
RoutingConfiguration rc = new RoutingConfiguration();
rc.SoapProcessingEnabled = false;

Configuration dynamique

Lorsque vous ajoutez des points de terminaison clients supplémentaires ou que vous devez modifier les filtres utilisés pour acheminer les messages, vous devez disposer d’un moyen de mettre à jour la configuration dynamiquement au moment de l’exécution pour empêcher l’interruption du service vers les points de terminaison qui reçoivent actuellement des messages via le service de routage. La modification d’un fichier de configuration ou du code de l’application hôte n’est pas toujours suffisante, car l’une ou l’autre méthode nécessite le recyclage de l’application, ce qui entraînerait la perte potentielle de messages en transit et le risque d’interruption pendant le redémarrage du service.

Vous pouvez uniquement modifier routingConfiguration par programmation. Bien que vous puissiez initialement configurer le service à l’aide d’un fichier de configuration, vous pouvez uniquement modifier la configuration au moment de l’exécution en construisant un nouveau RoutingConfiguration et en le transmettant en tant que paramètre à la ApplyConfiguration méthode exposée par l’extension de RoutingExtension service. Tous les messages en transit continuent d’être routés à l’aide de la configuration précédente, tandis que les messages reçus après l’appel à ApplyConfiguration utilisent la nouvelle configuration. L’exemple suivant illustre la création d’une instance du service de routage, puis la modification de la configuration.

RoutingConfiguration routingConfig = new RoutingConfiguration();
routingConfig.RouteOnHeadersOnly = true;
routingConfig.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
RoutingBehavior routing = new RoutingBehavior(routingConfig);
routerHost.Description.Behaviors.Add(routing);
routerHost.Open();
// Construct a new RoutingConfiguration
RoutingConfiguration rc2 = new RoutingConfiguration();
ServiceEndpoint clientEndpoint = new ServiceEndpoint();
ServiceEndpoint clientEndpoint2 = new ServiceEndpoint();
// Add filters to the FilterTable in the new configuration
rc2.FilterTable.add(new MatchAllMessageFilter(),
       new List<ServiceEndpoint>() { clientEndpoint });
rc2.FilterTable.add(new MatchAllMessageFilter(),
       new List<ServiceEndpoint>() { clientEndpoint2 });
rc2.RouteOnHeadersOnly = false;
// Apply the new configuration to the Routing Service hosted in
routerHost.routerHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc2);

Remarque

Lors de la mise à jour du service de routage de cette manière, il est uniquement possible de passer une nouvelle configuration. Il n’est pas possible de modifier uniquement les éléments sélectionnés de la configuration actuelle ou d’ajouter de nouvelles entrées à la configuration actuelle ; vous devez créer et passer une nouvelle configuration qui remplace celle existante.

Remarque

Toutes les sessions ouvertes à l’aide de la configuration précédente continuent à utiliser la configuration précédente. La nouvelle configuration est utilisée uniquement par les nouvelles sessions.

Gestion des erreurs

Si un CommunicationException est rencontré lors de la tentative d’envoi d’un message, la gestion des erreurs s'opère. Ces exceptions indiquent généralement qu’un problème a été rencontré lors de la tentative de communication avec le point de terminaison client défini, tel qu’un EndpointNotFoundException, ServerTooBusyExceptionou CommunicationObjectFaultedException. Le code de gestion des erreurs intercepte également et tente de réessayer d’envoyer lorsqu’un TimeoutException événement se produit, qui est une autre exception courante qui n’est pas dérivée de CommunicationException.

Lorsque l’une des exceptions précédentes se produit, le service de routage bascule vers une liste de points de terminaison de sauvegarde. Si tous les points de terminaison de sauvegarde échouent avec un échec de communication ou si un point de terminaison retourne une exception qui indique un échec dans le service de destination, le service de routage retourne une erreur à l’application cliente.

Remarque

La fonctionnalité de gestion des erreurs capture et gère les exceptions qui se produisent lors de la tentative d’envoi d’un message et lors de la tentative de fermeture d’un canal. Le code de gestion des erreurs n'est pas destiné à détecter ou gérer les exceptions créées par les points de terminaison d'application avec lesquels il communique, une FaultException exception levée par un service apparaît au service de routage en tant que FaultMessage et est transmis au client.

Si une erreur se produit lorsque le service de routage tente de relayer un message, vous pouvez obtenir un FaultException côté client, plutôt que d’obtenir EndpointNotFoundException normalement en l’absence du service de routage. Un service de routage peut donc masquer les exceptions et ne pas fournir une transparence totale, sauf si vous examinez les exceptions imbriquées.

Suivi d'exceptions

Lors de l’envoi d’un message à un point de terminaison dans une liste échoue, le service de routage trace les données d’exception résultantes et joint les détails de l’exception en tant que propriété de message nommée Exceptions. Cela conserve les données d’exception et permet à un utilisateur d’accéder par programme via un inspecteur de message. Les données d’exception sont stockées par message dans un dictionnaire qui mappe le nom du point de terminaison aux détails de l’exception rencontrés lors de la tentative d’envoi d’un message.

Points d'accès de sauvegarde

Chaque entrée de filtre dans la table de filtres peut éventuellement spécifier une liste de points de terminaison de sauvegarde, qui sont utilisés en cas d’échec de transmission lors de l’envoi au point de terminaison principal. Si une telle défaillance se produit, le service de routage tente de transmettre le message à la première entrée de la liste des points de terminaison de sauvegarde. Si cette tentative d’envoi rencontre également un échec de transmission, le point de terminaison suivant de la liste de sauvegarde est essayé. Le service de routage continue d’envoyer le message à chaque point de terminaison de la liste jusqu’à ce que le message soit reçu, que tous les points de terminaison retournent un échec de transmission ou qu’un échec de non-transmission soit retourné par un point de terminaison.

Les exemples suivants configurent le service de routage pour utiliser une liste de sauvegarde.

<routing>
  <filters>
    <!-- Create a MatchAll filter that catches all messages -->
    <filter name="MatchAllFilter1" filterType="MatchAll" />
  </filters>
  <filterTables>
    <!-- Set up the Routing Service's Message Filter Table -->
    <filterTable name="filterTable1">
        <!-- Add an entry that maps the MatchAllMessageFilter to the dead destination -->
        <!-- If that endpoint is down, tell the Routing Service to try the endpoints -->
        <!-- Listed in the backupEndpointList -->
        <add filterName="MatchAllFilter1" endpointName="deadDestination" backupList="backupEndpointList"/>
    </filterTable>
  </filterTables>
  <!-- Create the backup endpoint list -->
  <backupLists>
    <!-- Add an endpoint list that contains the backup destinations -->
    <backupList name="backupEndpointList">
      <add endpointName="realDestination" />
      <add endpointName="backupDestination" />
    </backupList>
  </backupLists>
</routing>
//create the endpoint list that contains the service endpoints we want to route to
List<ServiceEndpoint> backupList = new List<ServiceEndpoint>();
//add the endpoints in the order that the Routing Service should contact them
//first add the endpoint that we know is down
//clearly, normally you wouldn't know that this endpoint was down by default
backupList.Add(fakeDestination);
//then add the real Destination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationException when sending
//to the previous endpoint in the list.
backupList.Add(realDestination);
//add the backupDestination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationsException when sending
//to the previous endpoints in the list
backupList.Add(backupDestination);
//create the default RoutingConfiguration option
RoutingConfiguration rc = new RoutingConfiguration();
//add a MatchAll filter to the Routing Configuration's filter table
//map it to the list of endpoints defined above
//when a message matches this filter, it is sent to the endpoints in the list in order
//if an endpoint is down or does not respond (which the first endpoint won't
//since the client does not exist), the Routing Service automatically moves the message
//to the next endpoint in the list and try again.
rc.FilterTable.Add(new MatchAllMessageFilter(), backupList);

Modèles d’erreurs pris en charge

Le tableau suivant décrit les modèles compatibles avec l’utilisation des listes de points de terminaison de sauvegarde, ainsi que les notes décrivant les détails de la gestion des erreurs pour des modèles spécifiques.

Modèle session Transaction Contexte de réception Liste de sauvegarde prise en charge Remarques
One-Way Oui Tente de renvoyer le message sur un point de terminaison secondaire. Si ce message est en cours de multidiffusion, seul le message sur le canal ayant échoué est déplacé vers sa destination de sauvegarde.
One-Way ✔️ Non Une exception est levée et la transaction est annulée.
One-Way ✔️ Oui Tente de renvoyer le message sur un point de terminaison secondaire. Une fois que le message a été reçu avec succès, terminez tous les contextes de réception. Si le message n'a pas été correctement reçu par un point de terminaison, n'effectuez pas le contexte de réception.

Lorsque ce message est en cours de multidiffusion, le contexte de réception est terminé uniquement si le message est reçu avec succès par au moins un point de terminaison (principal ou sauvegarde). Si aucun des points de terminaison de l’un des chemins de multidiffusion ne reçoit correctement le message, ne terminez pas le contexte de réception.
One-Way ✔️ ✔️ Oui Abandonnez la transaction précédente, créez une nouvelle transaction et renvoyez tous les messages. Les messages qui ont rencontré une erreur sont transmis à une destination de sauvegarde.

Une fois qu’une transaction a été créée dans laquelle toutes les transmissions réussissent, terminez les contextes de réception et validez la transaction.
One-Way ✔️ Oui Tente de renvoyer le message sur un point de terminaison secondaire. Dans un scénario de multidiffusion, seuls les messages d’une session qui ont rencontré une erreur ou les messages d'une session dont la fermeture a échoué sont renvoyés aux destinations de sauvegarde.
One-Way ✔️ ✔️ Non Une exception est levée et la transaction est annulée.
One-Way ✔️ ✔️ Oui Tente de renvoyer le message sur un point de terminaison secondaire. Une fois tous les messages envoyés sans erreur, la session indique qu’aucun autre message n’est envoyé et que le service de routage ferme correctement tous les canaux de session sortants, tous les contextes de réception sont terminés et le canal de session entrant est fermé.
One-Way ✔️ ✔️ ✔️ Oui Abandonnez la transaction actuelle et créez-en une nouvelle. Renvoyez tous les messages précédents dans la session. Une fois qu’une transaction a été créée dans laquelle tous les messages ont été correctement envoyés et que la session n’indique plus de messages, tous les canaux de session sortant sont fermés, les contextes de réception sont tous terminés avec la transaction, le canal de session entrant est fermé et la transaction est validée.

Lorsque les sessions sont en cours de multidiffusion, les messages qui n’avaient aucune erreur sont réexpédiés à la même destination qu’auparavant, et les messages qui ont rencontré une erreur sont envoyés aux destinations de sauvegarde.
Bidirectionnel Oui Envoyer à une destination de sauvegarde. Une fois qu’un canal retourne un message de réponse, retournez la réponse au client d’origine.
Bidirectionnel ✔️ Oui Envoyez tous les messages sur le canal à une destination de sauvegarde. Une fois qu’un canal retourne un message de réponse, retournez la réponse au client d’origine.
Bidirectionnel ✔️ Non Une exception est levée et la transaction est annulée.
Bidirectionnel ✔️ ✔️ Non Une exception est levée et la transaction est annulée.
Duplex Non La communication duplex sans session n'est pas prise en charge actuellement.
Duplex ✔️ Oui Envoyer à une destination de sauvegarde.

Hébergement

Étant donné que le service de routage est implémenté en tant que service WCF, il doit être auto-hébergé dans une application ou hébergé par IIS ou WAS. Il est recommandé que le service de routage soit hébergé dans IIS, WAS ou une application de service Windows pour tirer parti des fonctionnalités de démarrage automatique et de gestion du cycle de vie disponibles dans ces environnements d’hébergement.

L’exemple suivant illustre l’hébergement du service de routage dans une application.

using (ServiceHost serviceHost =
                new ServiceHost(typeof(RoutingService)))

Pour héberger le service de routage dans IIS ou WAS, vous devez créer un fichier de service (.svc) ou utiliser l’activation basée sur la configuration du service. Lorsque vous utilisez un fichier de service, vous devez spécifier le paramètre Service avec RoutingService. L’exemple suivant contient un exemple de fichier de service qui peut être utilisé pour héberger le service de routage avec IIS ou WAS.

<%@ ServiceHost Language="C#" Debug="true" Service="System.ServiceModel.Routing.RoutingService,
     System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,
     PublicKeyToken=31bf3856ad364e35" %>

Service de routage et usurpation d'identité

Le service de routage WCF peut être utilisé avec l’emprunt d’identité pour l’envoi et la réception de messages. Toutes les contraintes Windows habituelles d’usurpation d’identité s’appliquent. Si vous devez configurer des autorisations de service ou de compte pour utiliser l'emprunt d'identité lors de l'écriture de votre service, vous devez effectuer ces mêmes étapes pour utiliser l'emprunt d'identité avec le service de routage. Pour plus d’informations, consultez Délégation et emprunt d’identité.

L'emprunt d'identité avec le service de routage requiert l'utilisation de l'emprunt d'identité ASP.NET en mode de compatibilité ASP.NET ou l'utilisation d'informations d'identification Windows qui ont été configurées pour permettre l'emprunt d'identité. Pour plus d’informations sur ASP.NET mode de compatibilité, consultez services WCF et ASP.NET.

Avertissement

Le service de routage WCF ne prend pas en charge l'emprunt d'identité avec l'authentification de base.

Pour utiliser l'emprunt d'identité ASP.NET avec le service de routage, activez le mode de compatibilité ASP.NET sur l'environnement d'hébergement de service. Le service de routage a déjà été marqué comme autorisant le mode de compatibilité ASP.NET et l’usurpation d’identité sera automatiquement activée. L’usurpation d'identité est la seule utilisation prise en charge de l’intégration d'ASP.NET au service de routage.

Pour utiliser l’usurpation des identifiants Windows avec le service de routage, vous devez configurer à la fois les identifiants et le service. L’objet d’informations d’identification du client (WindowsClientCredential, accessible à partir du ChannelFactory) définit une AllowedImpersonationLevel propriété qui doit être définie pour autoriser l’usurpation d'identité. Enfin, dans le service vous devez configurer le comportement ServiceAuthorizationBehavior pour affecter la valeur ImpersonateCallerForAllOperations à true. Le service de routage utilise cet indicateur pour déterminer s'il faut créer les clients pour transférer des messages lorsque l'emprunt d'identité est activé.

Voir aussi