Procedure: Dynamische update
In dit onderwerp worden de basisstappen beschreven die nodig zijn om de routeringsconfiguratie te maken en dynamisch bij te werken. In dit voorbeeld wordt de eerste routeringsconfiguratie verkregen uit het configuratiebestand en worden alle berichten gerouteerd naar de reguliere rekenmachineservice; het wordt echter programmatisch bijgewerkt om het doeleindpunt te wijzigen van de roundingCalc-service.
Notitie
In veel implementaties is de configuratie volledig dynamisch en is deze niet afhankelijk van een standaardconfiguratie; Er zijn echter enkele scenario's, zoals de scenario's in dit onderwerp, waarbij het wenselijk is om een standaardconfiguratiestatus te hebben wanneer de service wordt gestart.
Notitie
Dynamische updates worden alleen in het geheugen uitgevoerd en resulteren niet in de wijziging van configuratiebestanden.
Zowel regularCalc als roundingCalc ondersteunen dezelfde bewerkingen van optellen, aftrekken, vermenigvuldigen en delen; Met afrondingsberekening worden echter alle berekeningen afgerond op de dichtstbijzijnde gehele waarde voordat ze worden geretourneerd. Er wordt een configuratiebestand gebruikt om de service te configureren om alle berichten naar de regularCalc-service te routeren. Nadat de routeringsservice is gestart, ApplyConfiguration wordt gebruikt om de service opnieuw te configureren om berichten naar de roundingCalc-service te routeren.
Initiële configuratie implementeren
Maak de basisconfiguratie van de routeringsservice door de service-eindpunten op te geven die door de service worden weergegeven. In het volgende voorbeeld wordt één service-eindpunt gedefinieerd, dat wordt gebruikt voor het ontvangen van berichten. Het definieert ook een clienteindpunt dat wordt gebruikt voor het verzenden van berichten naar de reguliere berekening.
<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>
Definieer het filter dat wordt gebruikt voor het routeren van berichten naar de doeleindpunten. In dit voorbeeld wordt het filter MatchAll gebruikt om alle berichten te routeren naar het reguliereCalcEndpoint dat eerder is gedefinieerd. In het volgende voorbeeld wordt de filter- en filtertabel gedefinieerd.
<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>
Als u binnenkomende berichten wilt evalueren op basis van de filters in de filtertabel, moet u de filtertabel koppelen aan de service-eindpunten met behulp van het routeringsgedrag. In het volgende voorbeeld ziet u hoe u filterTable1 aan het service-eindpunt kunt koppelen.
<behaviors> <!--default routing service behavior definition--> <serviceBehaviors> <behavior name="routingConfiguration"> <routing filterTableName="filterTable1" /> </behavior> </serviceBehaviors> </behaviors>
Dynamische configuratie implementeren
Dynamische configuratie van de routeringsservice kan alleen in code worden uitgevoerd door een nieuwe RoutingConfiguration en te gebruiken ApplyConfiguration om de huidige configuratie te vervangen. In dit voorbeeld wordt de routeringsservice zelf gehost in een consoletoepassing. Nadat de toepassing is gestart, kunt u de routeringsconfiguratie wijzigen door 'regelmatig' of 'afronden' in het consolevenster in te voeren om het doeleindpunt te configureren waarnaar berichten worden doorgestuurd; regularCalc wanneer 'regular' wordt ingevoerd, anders rondingCalc wanneer 'afronden' wordt ingevoerd.
De volgende
using
instructies moeten worden toegevoegd om de routeringsservice te ondersteunen.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;
De volgende code wordt gebruikt om de routeringsservice als consoletoepassing zelf te hosten. Hiermee initialiseert u de routeringsservice met behulp van de configuratie die in de vorige stap is beschreven, die zich in het configuratiebestand van de toepassing bevindt. De while-lus bevat de code die wordt gebruikt om de routeringsconfiguratie te wijzigen.
// 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") { .... } } }
Als u de routeringsconfiguratie dynamisch wilt bijwerken, moet er een nieuwe routeringsconfiguratie worden gemaakt. Dit moet alle eindpunten, filters en filtertabellen bevatten die vereist zijn voor de nieuwe routeringsconfiguratie, omdat deze de bestaande routeringsconfiguratie volledig vervangt. Als u de nieuwe routeringsconfiguratie wilt gebruiken, moet u de nieuwe configuratie aanroepen ApplyConfiguration en doorgeven.
Voeg de volgende code toe aan de while-lus die eerder is gedefinieerd, zodat de service opnieuw kan worden geconfigureerd op basis van gebruikersinvoer.
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; }
Notitie
Omdat de methode voor het leveren van een nieuwe RoutingConfiguration is opgenomen in de service-extensie RoutingExtension, kunnen nieuwe RoutingConfiguration-objecten overal in het WCF-uitbreidbaarheidsmodel worden geleverd dat een verwijzing naar de ServiceHost of ServiceExtensions (zoals in een andere ServiceExtension) heeft of kan verkrijgen.
Voorbeeld 1
Hier volgt een volledige lijst met de consoletoepassing die in dit voorbeeld wordt gebruikt:
//-----------------------------------------------------------------
// 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;
}
}
}
}
}
}
Voorbeeld 2
Hier volgt een volledige lijst van het configuratiebestand dat in dit voorbeeld wordt gebruikt:
<?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>