Partilhar via


Como: Atualização dinâmica

Este tópico descreve as etapas básicas necessárias para criar e atualizar dinamicamente a configuração de roteamento. Neste exemplo, a configuração de roteamento inicial é obtida do arquivo de configuração e roteia todas as mensagens para o serviço de calculadora regularCalc; no entanto, ele é posteriormente atualizado programaticamente para alterar o ponto de extremidade de destino do serviço roundingCalc.

Nota

Em muitas implementações, a configuração será totalmente dinâmica e não dependerá de uma configuração padrão; No entanto, existem alguns cenários, como o deste tópico, em que é desejável ter um estado de configuração padrão quando o serviço é iniciado.

Nota

As atualizações dinâmicas ocorrem apenas na memória e não resultam na modificação dos arquivos de configuração.

Tanto regularCalc como roundingCalc suportam as mesmas operações de adicionar, subtrair, multiplicar e dividir; no entanto, arredondamentoCalc arredonda todos os cálculos para o valor inteiro mais próximo antes de retornar. Um arquivo de configuração é usado para configurar o serviço para rotear todas as mensagens para o serviço regularCalc. Depois que o Serviço de Roteamento for iniciado, ApplyConfiguration será usado para reconfigurar o serviço para rotear mensagens para o serviço roundingCalc.

Implementar configuração inicial

  1. Crie a configuração básica do serviço de roteamento especificando os pontos de extremidade de serviço expostos pelo serviço. O exemplo a seguir define um único ponto de extremidade de serviço, que será usado para receber mensagens. Ele também define um ponto de extremidade do cliente que será usado para enviar mensagens para o regularCalc.

    <services>
      <service behaviorConfiguration="routingConfiguration"
               name="System.ServiceModel.Routing.RoutingService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/routingservice/router" />
          </baseAddresses>
        </host>
        <!--Set up the inbound endpoint for the Routing Service-->
        <endpoint address="calculator"
                  binding="wsHttpBinding"
                  name="routerEndpoint"
                  contract="System.ServiceModel.Routing.IRequestReplyRouter" />
      </service>
    </services>
    <client>
    <!--set up the destination endpoint-->
      <endpoint name="regularCalcEndpoint"
                address="net.tcp://localhost:9090/servicemodelsamples/service/"
                binding="netTcpBinding"
                contract="*" />
    </client>
    
  2. Defina o filtro usado para rotear mensagens para os pontos de extremidade de destino. Neste exemplo, o filtro MatchAll é usado para rotear todas as mensagens para o regularCalcEndpoint definido anteriormente. O exemplo a seguir define a tabela de filtros e filtros.

    <filters>
      <!--define the message filter-->
      <filter name="MatchAllFilter" filterType="MatchAll"/>
    </filters>
    <filterTables>
      <filterTable name="filterTable1">
          <!--add the filter to the message filter table-->
          <add filterName="MatchAllFilter" endpointName="regularCalcEndpoint"/>
      </filterTable>
    </filterTables>
    
  3. Para avaliar as mensagens de entrada em relação aos filtros contidos na tabela de filtros, você deve associar a tabela de filtros aos pontos de extremidade de serviço usando o comportamento de roteamento. O exemplo a seguir demonstra a associação "filterTable1" com o ponto de extremidade de serviço.

    <behaviors>
      <!--default routing service behavior definition-->
      <serviceBehaviors>
        <behavior name="routingConfiguration">
          <routing filterTableName="filterTable1" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    

Implementar configuração dinâmica

A configuração dinâmica do Serviço de Roteamento só pode ser executada em código criando um novo RoutingConfiguration e usando ApplyConfiguration para substituir a configuração atual. Neste exemplo, o Serviço de Roteamento é auto-hospedado em um aplicativo de console. Depois que o aplicativo for iniciado, você poderá modificar a configuração de roteamento digitando 'regular' ou 'arredondamento' na janela do console para configurar o ponto de extremidade de destino para o qual as mensagens são roteadas; regularCalc quando 'regular' é inserido, caso contrário, arredondandoCalc quando 'arredondamento' é inserido.

  1. As diretivas a seguir using devem ser adicionadas para oferecer suporte ao Serviço de Roteamento.

    using System;
    using System.Collections.Generic;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher;
    using System.ServiceModel.Routing;
    
  2. O código a seguir é usado para hospedar automaticamente o Serviço de Roteamento como um aplicativo de console. Isso inicializa o Serviço de Roteamento usando a configuração descrita na etapa anterior, que está contida no arquivo de configuração do aplicativo. O loop while contém o código usado para alterar a configuração de roteamento.

    // Host the service within this EXE console application.
    public static void Main()
    {
        // Create a ServiceHost for the CalculatorService type.
        using (ServiceHost serviceHost =
            new ServiceHost(typeof(RoutingService)))
        {
            // Open the ServiceHost to create listeners
            // and start listening for messages.
            Console.WriteLine("The Routing Service configured, opening....");
            serviceHost.Open();
            Console.WriteLine("The Routing Service is now running.");
             Console.WriteLine("Type 'quit' to terminate router.");
             Console.WriteLine("<ENTER> to change routing configuration.");
             while (Console.ReadLine() != "quit")
             {
            ....
            }
        }
    }
    
  3. Para atualizar dinamicamente a configuração de roteamento, uma nova configuração de roteamento deve ser criada. Isso deve conter todos os pontos de extremidade, filtros e tabelas de filtros necessários para a nova configuração de roteamento, pois substituirá completamente a configuração de roteamento existente. Para usar a nova configuração de roteamento, você deve invocar ApplyConfiguration e passar a nova configuração.

    Adicione o seguinte código ao loop while definido anteriormente para permitir que o serviço seja reconfigurado com base na entrada do usuário.

    Console.WriteLine("Enter 'regular' or 'rounding' to set the destination endpoint:");
    string destEndpoint = Console.ReadLine();
    // Create a new RoutingConfiguration
    RoutingConfiguration rc = new RoutingConfiguration();
    // Determine the endpoint to configure for
    switch (destEndpoint)
    {
        case "regular":
            // Define the destination endpoint
            ServiceEndpoint regularCalc = new ServiceEndpoint(
               ContractDescription.GetContract(typeof(IRequestReplyRouter)),
               new NetTcpBinding(),
               new EndpointAddress("net.tcp://localhost:9090/servicemodelsamples/service/"));
            // Create a MatchAll filter and add to the filter table
            rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { regularCalc });
            // Use ApplyConfiguration to update the Routing Service
            serviceHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc);
            Console.WriteLine("Applied new routing configuration.");
            break;
        case "rounding":
            // Define the destination endpoint
            ServiceEndpoint roundingCalc = new ServiceEndpoint(
               ContractDescription.GetContract(typeof(IRequestReplyRouter)),
               new NetTcpBinding(),
               new EndpointAddress("net.tcp://localhost:8080/servicemodelsamples/service/"));
            // Create a MatchAll filter and add to the filter table
            rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { roundingCalc });
            // Use ApplyConfiguration to update the Routing Service
            serviceHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc);
            Console.WriteLine("Applied new routing configuration.");
            break;
        default:
            Console.WriteLine("Incorrect value entered, no change.");
            break;
    }
    

    Nota

    Como o método para fornecer uma nova RoutingConfiguration está contido na extensão de serviço RoutingExtension, novos objetos RoutingConfiguration podem ser fornecidos em qualquer lugar no modelo de extensibilidade do WCF que tenha ou possa obter uma referência ao ServiceHost ou ServiceExtensions (como em outro ServiceExtension).

Exemplo 1

A seguir está uma lista completa do aplicativo de console usado neste exemplo:

//-----------------------------------------------------------------
//  Copyright (c) Microsoft Corporation.  All Rights Reserved.
//-----------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Routing;

namespace Microsoft.Samples.AdvancedFilters
{
    public class Router
    {
        // Host the service within this EXE console application.
        public static void Main()
        {
            // Create a ServiceHost for the CalculatorService type.
            using (ServiceHost serviceHost =
                new ServiceHost(typeof(RoutingService)))
            {
                // Open the ServiceHost to create listeners
                // and start listening for messages.
                Console.WriteLine("The Routing Service configured, opening....");
                serviceHost.Open();
                Console.WriteLine("The Routing Service is now running.");
                Console.WriteLine("Type 'quit' to terminate router.");
                Console.WriteLine("<ENTER> to change routing configuration.");
                while (Console.ReadLine() != "quit")
                {
                    Console.WriteLine("Enter 'regular' or 'rounding' to set the destination endpoint:");
                    string destEndpoint = Console.ReadLine();
                    // Create a new RoutingConfiguration
                    RoutingConfiguration rc = new RoutingConfiguration();
                    // Determine the endpoint to configure for
                    switch (destEndpoint)
                    {
                        case "regular":
                            // Define the destination endpoint
                            ServiceEndpoint regularCalc = new ServiceEndpoint(
                            ContractDescription.GetContract(typeof(IRequestReplyRouter)),
                            new NetTcpBinding(),
                            new EndpointAddress("net.tcp://localhost:9090/servicemodelsamples/service/"));
                            // Create a MatchAll filter and add to the filter table
                            rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { regularCalc });
                            // Use ApplyConfiguration to update the Routing Service
                            serviceHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc);
                            Console.WriteLine("Applied new routing configuration.");
                            break;
                        case "rounding":
                            // Define the destination endpoint
                            ServiceEndpoint roundingCalc = new ServiceEndpoint(
                                ContractDescription.GetContract(typeof(IRequestReplyRouter)),
                                new NetTcpBinding(),
                                new EndpointAddress("net.tcp://localhost:8080/servicemodelsamples/service/"));
                            // Create a MatchAll filter and add to the filter table
                            rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { roundingCalc });
                            // Use ApplyConfiguration to update the Routing Service
                            serviceHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc);
                            Console.WriteLine("Applied new routing configuration.");
                            break;
                        default:
                            Console.WriteLine("Incorrect value entered, no change.");
                            break;
                    }
                }
            }
        }
    }
}

Exemplo 2

A seguir está uma lista completa do arquivo de configuração usado neste exemplo:

<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright (c) Microsoft Corporation. All rights reserved -->
<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="routingConfiguration"
               name="System.ServiceModel.Routing.RoutingService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/routingservice/router" />
          </baseAddresses>
        </host>
        <!--Set up the inbound endpoint for the Routing Service-->
        <endpoint address="calculator"
                  binding="wsHttpBinding"
                  name="routerEndpoint"
                  contract="System.ServiceModel.Routing.IRequestReplyRouter" />
      </service>
    </services>
    <behaviors>
      <!--default routing service behavior definition-->
      <serviceBehaviors>
        <behavior name="routingConfiguration">
          <routing filterTableName="filterTable1" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <client>
<!--set up the destination endpoint-->
      <endpoint name="regularCalcEndpoint"
                address="net.tcp://localhost:9090/servicemodelsamples/service/"
                binding="netTcpBinding"
                contract="*" />
    </client>
    <routing>

      <filters>
        <!--define the message filter-->
        <filter name="MatchAllFilter" filterType="MatchAll"/>
      </filters>
      <filterTables>
        <filterTable name="filterTable1">
            <!--add the filter to the message filter table-->
            <add filterName="MatchAllFilter" endpointName="regularCalcEndpoint"/>
        </filterTable>
      </filterTables>
    </routing>
  </system.serviceModel>
</configuration>

Consulte também