Udostępnij za pośrednictwem


Instrukcje: Aktualizacja dynamiczna

W tym temacie opisano podstawowe kroki wymagane do utworzenia i dynamicznego aktualizowania konfiguracji routingu. W tym przykładzie początkowa konfiguracja routingu jest uzyskiwana z pliku konfiguracji i kieruje wszystkie komunikaty do usługi zwykłego kalkulatora obliczeń; jednak programowo jest aktualizowany w celu zmiany docelowego punktu końcowego usługi roundingCalc.

Uwaga

W wielu implementacjach konfiguracja będzie w pełni dynamiczna i nie będzie polegać na konfiguracji domyślnej; Jednak istnieją pewne scenariusze, takie jak ten w tym temacie, gdzie pożądane jest, aby po uruchomieniu usługi miał domyślny stan konfiguracji.

Uwaga

Aktualizacje dynamiczne są wykonywane tylko w pamięci i nie powodują modyfikacji plików konfiguracji.

Zarówno regularCalc, jak i roundingCalc obsługują te same operacje dodawania, odejmowania, mnożenia i dzielenia; jednak funkcja RoundingCalc zaokrągla wszystkie obliczenia do najbliższej wartości całkowitej przed zwróceniem. Plik konfiguracji służy do konfigurowania usługi w celu kierowania wszystkich komunikatów do regularnej usługiCalc. Po uruchomieniu ApplyConfiguration usługi routingu jest używana do ponownej konfiguracji usługi w celu kierowania komunikatów do usługi roundingCalc.

Implementowanie konfiguracji początkowej

  1. Utwórz podstawową konfigurację usługi routingu, określając punkty końcowe usługi uwidocznione przez usługę. W poniższym przykładzie zdefiniowano pojedynczy punkt końcowy usługi, który będzie używany do odbierania komunikatów. Definiuje również punkt końcowy klienta, który będzie używany do wysyłania komunikatów do zwykłego obliczania.

    <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. Zdefiniuj filtr używany do kierowania komunikatów do docelowych punktów końcowych. W tym przykładzie filtr MatchAll służy do kierowania wszystkich komunikatów do zdefiniowanego wcześniej punktu regularnegoCalcEndpoint. W poniższym przykładzie zdefiniowano tabelę filtru i filtru.

    <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. Aby ocenić komunikaty przychodzące względem filtrów zawartych w tabeli filtrów, należy skojarzyć tabelę filtrów z punktami końcowymi usługi przy użyciu zachowania routingu. W poniższym przykładzie pokazano skojarzenie elementu "filterTable1" z punktem końcowym usługi.

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

Implementowanie konfiguracji dynamicznej

Dynamiczna konfiguracja usługi routingu może być wykonywana tylko w kodzie, tworząc nową RoutingConfiguration i używając polecenia ApplyConfiguration , aby zastąpić bieżącą konfigurację. W tym przykładzie usługa routingu jest hostowana samodzielnie w aplikacji konsolowej. Po uruchomieniu aplikacji można zmodyfikować konfigurację routingu, wprowadzając "regularne" lub "zaokrąglanie" w oknie konsoli, aby skonfigurować docelowy punkt końcowy, do którego są kierowane komunikaty; regularCalc po wprowadzeniu elementu "regular", w przeciwnym razie zaokrąglanie obliczania po wprowadzeniu zaokrąglania.

  1. Aby obsługiwać usługę routingu, należy dodać następujące using dyrektywy.

    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. Poniższy kod służy do samodzielnego hostowania usługi routingu jako aplikacji konsolowej. Spowoduje to zainicjowanie usługi routingu przy użyciu konfiguracji opisanej w poprzednim kroku, która znajduje się w pliku konfiguracji aplikacji. Pętla while zawiera kod używany do zmiany konfiguracji routingu.

    // 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. Aby dynamicznie aktualizować konfigurację routingu, należy utworzyć nową konfigurację routingu. Musi zawierać wszystkie punkty końcowe, filtry i tabele filtrów wymagane dla nowej konfiguracji routingu, ponieważ całkowicie zastąpi istniejącą konfigurację routingu. Aby użyć nowej konfiguracji routingu, należy wywołać ApplyConfiguration i przekazać nową konfigurację.

    Dodaj następujący kod do pętli while zdefiniowanej wcześniej, aby umożliwić ponowne skonfigurowanie usługi na podstawie danych wejściowych użytkownika.

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

    Uwaga

    Ponieważ metoda dostarczania nowego routinguConfiguration jest zawarta w rozszerzeniu usługi RoutingExtension, nowe obiekty RoutingConfiguration można udostępnić w dowolnym miejscu w modelu rozszerzalności programu WCF, który ma lub może uzyskać odwołanie do serviceHost lub ServiceExtensions (na przykład w innej usłudze ServiceExtension).

Przykład 1

Poniżej przedstawiono pełną listę aplikacji konsolowej używanej w tym przykładzie:

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

Przykład 2

Poniżej znajduje się pełna lista pliku konfiguracji używanego w tym przykładzie:

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

Zobacz też