Compartilhar via


Introdução ao roteamento

O Serviço de Roteamento fornece um intermediário SOAP plugável genérico que é capaz de rotear mensagens com base no conteúdo da mensagem. Com o Serviço de Roteamento, você pode criar uma lógica de roteamento complexa que permite implementar cenários como agregação de serviço, controle de versão do serviço, roteamento de prioridade e roteamento multicast. O Serviço de Roteamento também fornece tratamento de erros que permite configurar listas de pontos de extremidade de backup, para os quais as mensagens são enviadas se ocorrer uma falha ao enviar para o ponto de extremidade de destino primário.

Este tópico destina-se aos não habituados com o Serviço de Roteamento e aborda a configuração básica e a hospedagem do Serviço de Roteamento.

Configuração

O Serviço de Roteamento é implementado como um serviço WCF que expõe um ou mais pontos de extremidade de serviço que recebem mensagens de aplicativos cliente e roteiam as mensagens para um ou mais pontos de extremidade de destino. O serviço fornece um RoutingBehavior, que é aplicado aos pontos de extremidade de serviço expostos pelo serviço. Esse comportamento é usado para configurar vários aspectos de como o serviço opera. Para facilitar a configuração ao usar um arquivo de configuração, os parâmetros são especificados no RoutingBehavior. Em cenários baseados em código, esses parâmetros seriam especificados como parte de um objeto RoutingConfiguration, que pode ser passado para um RoutingBehavior.

Ao iniciar, esse comportamento adiciona o SoapProcessingBehavior, que é usado para executar o processamento SOAP de mensagens, aos pontos de extremidade do cliente. Isso permite que o Serviço de Roteamento transmita mensagens para pontos de extremidade que exigem uma MessageVersion diferente do ponto de extremidade em que a mensagem foi recebida. O RoutingBehavior também registra uma extensão de serviço, que RoutingExtensionfornece um ponto de acessibilidade para modificar a configuração do Serviço de Roteamento em tempo de execução.

A classe RoutingConfiguration fornece um meio consistente de configurar e atualizar a configuração do Serviço de Roteamento. Ele contém parâmetros que atuam como as configurações do Serviço de Roteamento e é usado para configurar o RoutingBehavior quando o serviço é iniciado ou é passado para a RoutingExtension para modificar a configuração de roteamento em tempo de execução.

A lógica de roteamento usada para executar o roteamento baseado em conteúdo de mensagens é definida agrupando vários objetos MessageFilter em tabelas de filtros (objetos MessageFilterTable<TFilterData>). As mensagens de entrada são avaliadas em relação aos filtros de mensagem contidos na tabela de filtros e para cada MessageFilter que corresponde à mensagem, encaminhadas para um ponto de extremidade de destino. A tabela de filtros que deve ser usada para rotear mensagens é especificada usando o RoutingBehavior na configuração ou por meio do código, usando o objeto RoutingConfiguration.

Definindo pontos de extremidade

Embora possa parecer que você deve iniciar sua configuração definindo a lógica de roteamento que usará, a primeira etapa deverá ser determinar a forma dos pontos de extremidade para os quais você roteará mensagens. O Serviço de Roteamento usa contratos que definem a forma dos canais usados para receber e enviar mensagens e, portanto, a forma do canal de entrada deve corresponder à do canal de saída. Por exemplo, se estiver roteando para pontos de extremidade que usam a forma do canal de solicitação-resposta, você deverá usar um contrato compatível nos pontos de extremidade de entrada, como o IRequestReplyRouter.

Isso significa que, se os pontos de extremidade de destino usarem contratos com vários padrões de comunicação (como a combinação de operações unidirecionais e bidirecionais), você não poderá criar um único ponto de extremidade de serviço que possa receber e rotear mensagens para todos eles. Você deve determinar quais pontos de extremidade têm formas compatíveis e definir um ou mais pontos de extremidade de serviço que serão usados para receber mensagens a serem roteadas para os pontos de extremidade de destino.

Observação

Ao trabalhar com contratos que especificam vários padrões de comunicação (como uma combinação de operações unidirecionais e bidirecionais), uma solução alternativa é usar um contrato duplex no Serviço de Roteamento, como IDuplexSessionRouter. No entanto, isso significa que a associação deve ser capaz de comunicação duplex, o que pode não ser possível para todos os cenários. Em cenários em que isso não é possível, pode ser necessário considerar a comunicação em vários pontos de extremidade ou modificar o aplicativo.

Para obter mais informações sobre contratos de roteamento, consulte Contratos de roteamento.

Depois que o ponto de extremidade de serviço for definido, você poderá usar o RoutingBehavior para associar um RoutingConfiguration específico ao ponto de extremidade. Ao configurar o Serviço de Roteamento usando um arquivo de configuração, o RoutingBehavior é usado para especificar a tabela de filtros que contém a lógica de roteamento usada para processar mensagens recebidas nesse ponto de extremidade. Se você estiver configurando o Serviço de Roteamento programaticamente, poderá especificar a tabela de filtros usando o RoutingConfiguration.

O exemplo a seguir define os pontos de extremidade de serviço e cliente que são usados pelo Serviço de Roteamento de forma programática e usando um arquivo de configuração.

<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));

Este exemplo configura o Serviço de Roteamento para expor um único ponto de extremidade com um endereço de http://localhost:8000/routingservice/router, o qual é usado para receber mensagens a serem roteadas. Como as mensagens são roteadas para pontos de extremidade de solicitação e resposta, o ponto de extremidade de serviço usa o contrato IRequestReplyRouter. Essa configuração também define um único ponto de extremidade do cliente de http://localhost:8000/servicemodelsample/service para o qual as mensagens são roteadas. A tabela de filtros (não mostrada) chamada "routingTable1" contém a lógica de roteamento usada para rotear mensagens, sendo associada ao ponto de extremidade de serviço usando o RoutingBehavior (para um arquivo de configuração) ou RoutingConfiguration (para configuração programática).

Lógica de roteamento

Para definir a lógica de roteamento usada para rotear mensagens, você deve determinar quais dados contidos nas mensagens de entrada podem ser acionados exclusivamente. Por exemplo, se todos os pontos de extremidade de destino que você está roteando são para compartilhar as mesmas Ações SOAP, o valor da Ação contida na mensagem não será um bom indicador para qual ponto de extremidade específico a mensagem deve ser roteada. Se você precisar rotear mensagens exclusivamente para um ponto de extremidade específico, deverá filtrar dados que identifiquem exclusivamente o ponto de extremidade de destino para o qual a mensagem é roteada.

O Serviço de Roteamento fornece várias implementações de MessageFilter que inspecionam valores específicos dentro da mensagem, como o endereço, ação, nome do ponto de extremidade ou até mesmo uma consulta XPath. Se nenhuma dessas implementações atender às suas necessidades, você poderá criar uma implementação personalizada do MessageFilter. Para obter mais informações sobre filtros de mensagem e uma comparação das implementações usadas pelo Serviço de Roteamento, consulte Filtros de Mensagens e Escolher um Filtro.

Vários filtros de mensagem são organizados juntos em tabelas de filtros, que associam cada MessageFilter a um ponto de extremidade de destino. Opcionalmente, a tabela de filtros também pode ser usada para especificar uma lista de pontos de extremidade de backup para os quais o Serviço de Roteamento tentará enviar a mensagem em caso de falha de transmissão.

Por padrão, todos os filtros de mensagem dentro de uma tabela de filtros são avaliados simultaneamente; no entanto, você pode especificar uma Priority que faz com que os filtros de mensagem sejam avaliados em uma ordem específica. Todas as entradas com a prioridade mais alta são avaliadas primeiro e os filtros de mensagem de prioridades mais baixas não são avaliados se uma correspondência for encontrada em um nível de prioridade mais alto. Para obter mais informações sobre tabelas de filtros, consulte Filtros de Mensagem.

Os exemplos a seguir usam o MatchAllMessageFilter, que é avaliado como true para todas as mensagens. Este MessageFilter é adicionado à tabela de filtros "routingTable1", que associa o MessageFilter ao ponto de extremidade do cliente chamado "CalculatorService". O RoutingBehavior especifica que essa tabela deve ser usada para rotear mensagens processadas pelo ponto de extremidade de serviço.

<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);

Observação

Por padrão, o Serviço de Roteamento avalia apenas os cabeçalhos da mensagem. Para permitir que os filtros acessem o corpo da mensagem, você deve definir RouteOnHeadersOnly como false.

Multicast

Embora muitas configurações do Serviço de Roteamento usem a lógica de filtro exclusiva que roteia mensagens para apenas um ponto de extremidade específico, talvez seja necessário rotear uma determinada mensagem para vários pontos de extremidade de destino. Para o multicast de uma mensagem para vários destinos, as seguintes condições devem ser verdadeiras:

  • A forma do canal não deve ser solicitação-resposta (embora possa ser unidirecional ou duplex), porque a solicitação-resposta exige que apenas uma resposta possa ser recebida pelo aplicativo cliente em resposta à solicitação.

  • Vários filtros devem retornar true ao avaliarem a mensagem.

Se essas condições forem atendidas, a mensagem será roteada para todos os pontos de extremidade de todos os filtros avaliados como true. O exemplo a seguir define uma configuração de roteamento que resulta em mensagens sendo roteadas para ambos os pontos de extremidade se o endereço do ponto de extremidade na mensagem for 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);

Processamento SOAP

Para dar suporte ao roteamento de mensagens entre protocolos diferentes, o RoutingBehavior, por padrão, adiciona o SoapProcessingBehavior a todos os pontos de extremidade do cliente para os quais as mensagens são roteadas. Esse comportamento cria automaticamente uma nova MessageVersion antes de rotear a mensagem para o ponto de extremidade, bem como criar uma MessageVersion compatível para qualquer documento de resposta antes de devolvê-la ao aplicativo cliente solicitante.

As etapas executadas para criar uma nova MessageVersion para a mensagem de saída são as seguintes:

Processamento de solicitação

  • Obtenha a MessageVersion da associação/canal de saída.

  • Obtenha o leitor de corpo da mensagem original.

  • Crie uma nova mensagem com a mesma ação, um leitor de corpo e uma nova MessageVersion.

  • Se Addressing != Addressing.None, copie os cabeçalhos To, From, FaultTo e RelatesTo para a nova mensagem.

  • Copie todas as propriedades da mensagem para a nova mensagem.

  • Armazene a mensagem de solicitação original a ser usada ao processar a resposta.

  • Retorne a nova mensagem de solicitação.

Processamento de resposta

  • Obtenha a MessageVersion da mensagem de solicitação original.

  • Obtenha o leitor de corpo da mensagem de resposta recebida.

  • Crie uma nova mensagem de resposta com a mesma ação, o leitor de corpo e a MessageVersion da mensagem de solicitação original.

  • Se Addressing != Addressing.None, copie os cabeçalhos To, From, FaultTo e RelatesTo para a nova mensagem.

  • Copie as propriedades da mensagem para a nova mensagem.

  • Retorne a nova mensagem de resposta.

Por padrão, o SoapProcessingBehavior é adicionado automaticamente aos pontos de extremidade do cliente pelo RoutingBehavior momento em que o serviço é iniciado; no entanto, você pode controlar se o processamento SOAP é adicionado a todos os pontos de extremidade do cliente usando a SoapProcessingEnabled propriedade. Você também pode adicionar o comportamento diretamente a um ponto de extremidade específico e habilitar ou desabilitar esse comportamento no nível do ponto de extremidade se for necessário um controle mais granular do processamento SOAP.

Observação

Se o processamento SOAP estiver desabilitado para um ponto de extremidade que exija uma MessageVersion diferente da mensagem de solicitação original, você deverá fornecer um mecanismo personalizado para executar as modificações SOAP necessárias antes de enviar a mensagem para o ponto de extremidade de destino.

Nos exemplos a seguir, a propriedade soapProcessingEnabled é usada para impedir que o SoapProcessingBehavior seja adicionado automaticamente a todos os pontos de extremidade do cliente.

<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;

Configuração dinâmica

Ao adicionar pontos de extremidade de cliente adicionais ou precisar modificar os filtros usados para rotear mensagens, você deve ter uma maneira de atualizar a configuração dinamicamente em tempo de execução para evitar interromper o serviço para os pontos de extremidade que estão recebendo mensagens no momento por meio do Serviço de Roteamento. Modificar um arquivo de configuração ou o código do aplicativo host nem sempre é suficiente, pois qualquer método requer a reciclagem do aplicativo, o que levaria à perda potencial de mensagens atualmente em trânsito e ao potencial de tempo de inatividade enquanto aguarda a reinicialização do serviço.

Você só pode modificar o RoutingConfiguration programaticamente. Embora você possa configurar inicialmente o serviço usando um arquivo de configuração, você só pode modificar a configuração em tempo de execução construindo um novo RoutingConfiguration e passando-o como um parâmetro para o método ApplyConfiguration exposto pela extensão de serviço RoutingExtension. Todas as mensagens atualmente em trânsito continuam a ser roteadas usando a configuração anterior, enquanto as mensagens recebidas após a chamada para ApplyConfiguration usam a nova configuração. O exemplo a seguir demonstra a criação de uma instância do Serviço de Roteamento e, em seguida, a modificação da configuração.

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);

Observação

Ao atualizar o Serviço de Roteamento dessa maneira, só é possível passar uma nova configuração. Não é possível modificar apenas elementos selecionados da configuração atual ou acrescentar novas entradas à configuração atual; você deve criar e passar uma nova configuração que substitua a existente.

Observação

Todas as sessões abertas usando a configuração anterior continuam usando a configuração anterior. A nova configuração é usada apenas por novas sessões.

Tratamento de erros

Se algum CommunicationException for encontrado ao tentar enviar uma mensagem, o tratamento de erros ocorrerá. Essas exceções normalmente indicam que um problema foi encontrado ao tentar se comunicar com o ponto de extremidade do cliente definido, como uma EndpointNotFoundException, ServerTooBusyException ou CommunicationObjectFaultedException O código de tratamento de erros também capturará e tentará repetir o envio quando ocorrer um TimeoutException, que é outra exceção comum que não é derivada de CommunicationException.

Quando ocorre uma das exceções anteriores, o Serviço de Roteamento faz uma transferência automática por falha para uma lista de pontos de extremidade de backup. Se todos os pontos de extremidade de backup falharem com uma falha de comunicação ou se um ponto de extremidade retornar uma exceção que indica uma falha no serviço de destino, o Serviço de Roteamento retornará uma falha para o aplicativo cliente.

Observação

A funcionalidade de tratamento de erros captura e manipula exceções que ocorrem ao tentar enviar uma mensagem e ao tentar fechar um canal. O código de tratamento de erros não se destina a detectar ou manipular exceções criadas pelos pontos de extremidade do aplicativo com os quais está se comunicando; uma FaultException gerada por um serviço aparece no Serviço de Roteamento como uma FaultMessage e é enviada de volta ao cliente.

Se ocorrer um erro quando o serviço de roteamento tentar retransmitir uma mensagem, você poderá obter uma FaultException no lado cliente, em vez de uma EndpointNotFoundException que você normalmente obteria na ausência do serviço de roteamento. Um serviço de roteamento pode mascarar exceções e não fornecer transparência total, a menos que você examine exceções aninhadas.

Exceções de rastreamento

Quando o envio de uma mensagem para um ponto de extremidade em uma lista falha, o Serviço de Roteamento rastreia os dados de exceção resultantes e anexa os detalhes da exceção como uma propriedade de mensagem chamada Exceções. Isso preserva os dados de exceção e permite o acesso programático de um usuário por meio de um inspetor de mensagens. Os dados de exceção são armazenados por mensagem em um dicionário que mapeia o nome do ponto de extremidade para os detalhes de exceção encontrados ao tentar enviar uma mensagem para ele.

Pontos de extremidade de backup

Cada entrada de filtro dentro da tabela de filtros pode, opcionalmente, especificar uma lista de pontos de extremidade de backup, que são usados no caso de uma falha de transmissão durante o envio para o ponto de extremidade primário. Se essa falha ocorrer, o Serviço de Roteamento tentará transmitir a mensagem para a primeira entrada na lista de pontos de extremidade de backup. Se essa tentativa de envio também encontrar uma falha de transmissão, será tentado o próximo ponto de extremidade na lista de backup. O Serviço de Roteamento continua enviando a mensagem para cada ponto de extremidade na lista até que a mensagem seja recebida com êxito, todos os pontos de extremidade retornem uma falha de transmissão ou uma falha de não transmissão seja retornada por um ponto de extremidade.

Os exemplos a seguir configuram o Serviço de Roteamento para usar uma lista de backup.

<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);

Padrões de erro com suporte

A tabela a seguir descreve os padrões compatíveis com o uso de listas de pontos de extremidade de backup, juntamente com anotações que descrevem os detalhes do tratamento de erros para padrões específicos.

Padrão Session Transação Contexto de recebimento. Lista de backup com suporte Observações
Unidirecional Sim Tenta reenviar a mensagem em um ponto de extremidade de backup. Se essa mensagem for objeto de transmissão múltipla (multicast), somente a mensagem no canal com falha será movida para seu destino de backup.
Unidirecional ✔️ No Uma exceção é gerada e a transação é revertida.
Unidirecional ✔️ Sim Tenta reenviar a mensagem em um ponto de extremidade de backup. Depois que a mensagem for recebida com êxito, conclua todos os contextos de recebimento. Se a mensagem não for recebida com êxito por nenhum ponto de extremidade, não conclua o contexto de recebimento.

Quando essa mensagem estiver sendo objeto de transmissão múltipla (multicast), o contexto de recebimento só será concluído se a mensagem for recebida com êxito por pelo menos um ponto de extremidade (primário ou backup) Se nenhum dos pontos de extremidade em nenhum dos caminhos de multicast receber a mensagem com êxito, não conclua o contexto de recebimento.
Unidirecional ✔️ ✔️ Sim Anule a transação anterior, crie uma nova transação e reenvia todas as mensagens. As mensagens que encontraram erro são transmitidas para um destino de backup.

Depois que uma transação for criada na qual todas as transmissões forem bem-sucedidas, conclua os contextos de recebimento e confirme a transação.
Unidirecional ✔️ Sim Tenta reenviar a mensagem em um ponto de extremidade de backup. Em um cenário multicast, somente as mensagens em uma sessão que tenham encontrado um erro ou em uma sessão cujo fechamento da sessão tenha falhado são reenviadas a destinos de backup.
Unidirecional ✔️ ✔️ No Uma exceção é gerada e a transação é revertida.
Unidirecional ✔️ ✔️ Sim Tenta reenviar a mensagem em um ponto de extremidade de backup. Depois que todas as mensagens são enviadas sem erro, a sessão indica que não há mais mensagens e o Serviço de Roteamento fecha com êxito todos os canais de sessão de saída, todos os contextos de recebimento são concluídos e o canal de sessão de entrada é fechado.
Unidirecional ✔️ ✔️ ✔️ Sim Anule a transação atual e crie uma nova. Reenvie todas as mensagens anteriores na sessão. Depois que uma transação foi criada na qual todas as mensagens foram enviadas com êxito e a sessão não indica mais mensagens, todos os canais de sessão de saída são fechados, os contextos de recebimento são todos concluídos com a transação, o canal de sessão de entrada é fechado e a transação é confirmada.

Quando as sessões estão sendo objeto de transmissão múltipla (multicast), as mensagens que não tinham erro são reenviadas com o mesmo destino de antes e as mensagens que encontraram um erro são enviadas para destinos de backup.
Bidirecional Sim Envie para um destino de backup. Depois que um canal retornar uma mensagem de resposta, retorne a resposta ao cliente original.
Bidirecional ✔️ Sim Envie todas as mensagens no canal para um destino de backup. Depois que um canal retornar uma mensagem de resposta, retorne a resposta ao cliente original.
Bidirecional ✔️ No Uma exceção é gerada e a transação é revertida.
Bidirecional ✔️ ✔️ No Uma exceção é gerada e a transação é revertida.
Duplex No No momento, não há suporte para comunicação duplex não-sessão.
Duplex ✔️ Sim Envie para um destino de backup.

Hosting

Como o Serviço de Roteamento é implementado como um serviço WCF, ele deve ser auto-hospedado em um aplicativo ou hospedado pelo IIS ou WAS. É recomendável que o Serviço de Roteamento seja hospedado no IIS, no WAS ou em um aplicativo de Serviço do Windows para aproveitar os recursos de gerenciamento automático de início e ciclo de vida disponíveis nesses ambientes de hospedagem.

O exemplo a seguir demonstra a hospedagem do Serviço de Roteamento em um aplicativo.

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

Para hospedar o Serviço de Roteamento no IIS ou no WAS, você deve criar um arquivo de serviço (.svc) ou usar a ativação baseada em configuração do serviço. Ao usar um arquivo de serviço, você deve especificar o RoutingService usando o parâmetro Serviço. O exemplo a seguir contém um arquivo de serviço de exemplo que pode ser usado para hospedar o Serviço de Roteamento com o IIS ou o WAS.

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

Serviço de roteamento e representação

O Serviço de Roteamento do WCF pode ser usado com representação para enviar e receber mensagens. Todas as restrições de representação habituais do Windows se aplicam. Se você precisar configurar permissões de serviço ou de conta para usar a representação ao gravar seu próprio serviço, precisará executar essas mesmas etapas para usar a representação com o serviço de roteamento. Para obter mais informações, consulte Delegação e representação.

A representação com o serviço de roteamento requer o uso do recurso representação ASP.NET enquanto estiver no modo de compatibilidade ASP.NET ou o uso de credenciais do Windows que foram configuradas para permitir a representação. Para obter mais informações sobre modo de compatibilidade ASP.NET, consulte Serviços WCF e ASP.NET.

Aviso

O Serviço de Roteamento do WCF não dá suporte à representação com autenticação básica.

Para usar o recurso de representação ASP.NET com o serviço de roteamento, habilite o modo de compatibilidade ASP.NET no ambiente de hospedagem do serviço. O serviço de roteamento já foi marcado como permitindo o modo de compatibilidade ASP.NET e a representação será habilitada automaticamente. A representação é o único uso com suporte da integração ASP.NET com o serviço de roteamento.

Para usar a representação de credencial do Windows com o serviço de roteamento, você precisa configurar as credenciais e o serviço. O objeto de credenciais do cliente (WindowsClientCredential, acessível do ChannelFactory) define uma propriedade AllowedImpersonationLevel que precisa ser definida para permitir a representação. Por fim, no serviço, você precisa configurar o comportamento ServiceAuthorizationBehavior para definir ImpersonateCallerForAllOperations como true. O serviço de roteamento usa esse sinalizador para decidir se os clientes devem ser criados para encaminhar mensagens com representação habilitada.

Confira também