Vorgehensweise: Dynamisches UpdateHow To: Dynamic Update

In diesem Thema werden die grundlegenden Schritte beschrieben, die erforderlich sind, um die Routingkonfiguration zu erstellen und dynamisch zu aktualisieren.This topic outlines the basic steps required to create and dynamically update the routing configuration. In diesem Beispiel wird die ursprüngliche Routingkonfiguration aus der Konfigurationsdatei abgerufen, die alle Nachrichten an den regularCalc-Rechnerdienst weiterleitet. Die Konfiguration wird anschließend jedoch programmgesteuert aktualisiert, um den Zielendpunkt in den roundingCalc-Dienst zu ändern.In this example, the initial routing configuration is obtained from the configuration file and routes all messages to the regularCalc calculator service; however, it is subsequently updated programmatically in order to change the destination endpoint the roundingCalc service.

Hinweis

In vielen Implementierungen läuft die Konfiguration komplett dynamisch ab und erfordert keine Standardkonfiguration. Es gibt jedoch einige Szenarien, z. B. die in diesem Thema, in denen es wünschenswert ist, dass beim Starten des Diensts ein Standardkonfigurationszustand herrscht.In many implementations, configuration will be fully dynamic and will not rely on a default configuration; however, there are some scenarios, such as the one in this topic, where it is desirable to have a default configuration state when the service starts.

Hinweis

Dynamische Updates treten nur im Arbeitsspeicher auf und führen nicht zur Änderung von Konfigurationsdateien.Dynamic updates occur only in memory, and do not result in the modification of configuration files.

regularCalc und roundingCalc unterstützen die gleichen Vorgänge zum Addieren, Subtrahieren, Mulltiplizieren und Dividieren. roundingCalc rundet alle Berechnungsergebnisse vor der Rückgabe jedoch auf den nächsten ganzzahligen Wert.Both regularCalc and roundingCalc support the same operations of add, subtract, multiply and divide; however, roundingCalc rounds all calculations to the nearest integer value before returning. Es wird eine Konfigurationsdatei verwendet, um den Dienst so zu konfigurieren, dass er alle Nachrichten an den regularCalc-Dienst weiterleitet.A configuration file is used to configure the service to route all messages to the regularCalc service. Nachdem der Routingdienst gestartet wurde, wird ApplyConfiguration für die Neukonfiguration des Diensts verwendet, um Nachrichten an den roundingCalc-Dienst weiterzuleiten.After the Routing Service has been started, ApplyConfiguration is used to reconfigure the service to route messages to the roundingCalc service.

Implementieren der AnfangskonfigurationImplement Initial Configuration

  1. Erstellen Sie die grundlegende Routingdienstkonfiguration, indem Sie die vom Dienst verfügbar gemachten Dienstendpunkte angeben.Create the basic Routing Service Configuration by specifying the service endpoints exposed by the service. Im folgenden Beispiel wird ein einzelner Dienstendpunkt definiert, der zum Empfangen von Nachrichten verwendet wird.The following example defines a single service endpoint, which will be used to receive messages. Außerdem wird ein Clientendpunkt definiert, der zum Senden von Nachrichten an regularCalc verwendet wird.It also defines a client endpoint that will be used to send messages to the 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. Definieren Sie den Filter, der verwendet wird, um Nachrichten an die Zielendpunkte weiterzuleiten.Define the filter used to route messages to the destination endpoints. In diesem Beispiel wird der MatchAll-Filter verwendet, um alle Nachrichten an den zuvor definierten regularCalcEndpoint weiterzuleiten.For this example, the MatchAll filter is used to route all messages to the regularCalcEndpoint defined previously. Im folgenden Beispiel werden der Filter und die Filtertabelle definiert.The following example defines the filter and filter table.

    <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. Um eingehende Nachrichten anhand der in der Filtertabelle enthaltenen Filter auszuwerten, müssen Sie den Dienstendpunkten die Filtertabelle mithilfe des Routingverhaltens zuordnen.To evaluate incoming messages against the filters contained in the filter table, you must associate the filter table with the service endpoints by using the routing behavior. Im folgende Beispiel veranschaulicht die Zuordnung von "filterTable1" mit dem Dienstendpunkt.The following example demonstrates associating "filterTable1" with the service endpoint.

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

Implementieren der dynamischen KonfigurationImplement Dynamic Configuration

Die dynamische Konfiguration des Routingdiensts kann nur per Code durchgeführt werden, indem ein neues RoutingConfiguration-Objekt erstellt und ApplyConfiguration verwendet wird, um die aktuelle Konfiguration zu ersetzen.Dynamic configuration of the Routing Service can only be performed in code by creating a new RoutingConfiguration and using ApplyConfiguration to replace the current configuration. Für dieses Beispiel wird der Routingdienst innerhalb einer Konsolenanwendung selbst gehostet.For this example, the Routing Service is self-hosted within a console application. Nachdem die Anwendung gestartet wurde, können Sie die Routingkonfiguration ändern. Geben Sie dazu am Konsolenfenster "regular" oder "rounding" ein, um den Zielendpunkt zu konfigurieren, an den Nachrichten weitergeleitet werden, also "regularCalc", wenn Sie "regular" eingeben, und "roundingCalc", wenn Sie "rounding" eingeben.After the application has started, you can modify the routing configuration by entering ‘regular’ or ‘rounding’ at the console window to configure the destination endpoint that messages are routed to; regularCalc when ‘regular’ is entered, otherwise roundingCalc when ‘rounding’ is entered.

  1. Die folgenden using-Anweisungen müssen hinzugefügt werden, um den Routingdienst zu unterstützen.The following using statements must be added in order to support the Routing Service.

    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. Der folgende Code wird verwendet, um den Routingdienst selbst als Konsolenanwendung hosten.The following code is used to self-host the Routing Service as a console application. Dadurch wird der Routingdienst mithilfe der Konfiguration initialisiert, die im vorherigen Schritt beschrieben wurde und in der Anwendungskonfigurationsdatei enthalten ist.This initializes the Routing Service using the configuration described in the previous step, which is contained within the application configuration file. Die while-Schleife enthält den Code, der zum Ändern der Routingkonfiguration verwendet wird.The while loop contains the code used to change the routing configuration.

    // 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. Um die Routingkonfiguration dynamisch zu aktualisieren, muss eine neue Routingkonfiguration erstellt werden.To dynamically update the routing configuration, a new routing configuration must be created. Diese muss alle Endpunkte, Filter und Filtertabellen enthalten, die für die neue Routingkonfiguration erforderlich sind, weil sie die vorhandene Routingkonfiguration vollständig ersetzt.This must contain all endpoints, filters and filter tables that are required for the new routing configuration, as it will completely replace the existing routing configuration. Um die neue Routingkonfiguration zu verwenden, müssen Sie ApplyConfiguration aufrufen und die neue Konfiguration übergeben.In order to use the new routing configuration, you must invoke ApplyConfiguration and pass the new configuration.

    Fügen Sie der zuvor definierten while-Schleife den folgenden Code hinzu, um es zu ermöglichen, dass der Dienst basierend auf der Benutzereingabe neu konfiguriert wird.Add the following code to the while loop defined previously to allow the service to be reconfigured based on user input.

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

    Hinweis

    Da die Methode zum Bereitstellen einer neuen RoutingConfiguration in der RoutingExtension-Diensterweiterung enthalten ist, können neue RoutingConfiguration-Objekte überall im WCF-Erweiterbarkeitsmodell bereitgestellt werden, sofern das Modell über einen Verweis auf ServiceHost oder ServiceExtensions (z. B. in einer anderen ServiceExtension) verfügt oder diesen abrufen kann.Since the method for providing a new RoutingConfiguration is contained in the RoutingExtension service extension, new RoutingConfiguration objects can be provided anywhere in the WCF extensibility model that has or can obtain a reference to the ServiceHost or ServiceExtensions (such as in another ServiceExtension). Ein Beispiel der RoutingConfiguration auf diese Weise dynamisch zu aktualisieren, finden Sie unter dynamische Neukonfiguration.For an example of dynamically updating the RoutingConfiguration in this manner, see Dynamic Reconfiguration.

BeispielExample

Es folgt eine vollständige Liste der Konsolenanwendung, die in diesem Beispiel verwendet wird.Following is a complete listing of the console application used in this example.

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

BeispielExample

Es folgt eine vollständige Liste der Konfigurationsdatei, die in diesem Beispiel verwendet wird.Following is a complete listing of the configuration file used in this example.

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

Siehe auchSee Also

RoutingdiensteRouting Services