Udostępnij za pośrednictwem


Wprowadzenie do routingu

Usługa routingu udostępnia ogólny pośredniczący protokół SOAP, który umożliwia routing komunikatów na podstawie zawartości komunikatów. Za pomocą usługi routingu można utworzyć złożoną logikę routingu, która umożliwia implementowanie scenariuszy, takich jak agregacja usługi, przechowywanie wersji usług, routing priorytetu i routing multiemisji. Usługa routingu udostępnia również obsługę błędów, która umożliwia skonfigurowanie list punktów końcowych kopii zapasowej, do których są wysyłane komunikaty w przypadku awarii podczas wysyłania do podstawowego punktu końcowego docelowego.

Ten temat jest przeznaczony dla nowych użytkowników usługi routingu i obejmuje podstawową konfigurację i hosting usługi routingu.

Konfigurowanie

Usługa routingu jest implementowana jako usługa WCF, która uwidacznia co najmniej jeden punkt końcowy usługi, który odbiera komunikaty z aplikacji klienckich i kieruje komunikaty do co najmniej jednego docelowego punktu końcowego. Usługa udostępnia element RoutingBehavior, który jest stosowany do punktów końcowych usługi udostępnianych przez usługę. To zachowanie służy do konfigurowania różnych aspektów działania usługi. Aby ułatwić konfigurację podczas korzystania z pliku konfiguracji, parametry są określone w routinguBehavior. W scenariuszach opartych na kodzie te parametry zostaną określone jako część RoutingConfiguration obiektu, który następnie można przekazać do elementu RoutingBehavior.

Podczas uruchamiania to zachowanie dodaje element SoapProcessingBehavior, który jest używany do przetwarzania komunikatów protokołu SOAP do punktów końcowych klienta. Dzięki temu usługa routingu może przesyłać komunikaty do punktów końcowych, które wymagają innego elementu MessageVersion niż punkt końcowy odebrany komunikat. Element RoutingBehavior rejestruje również rozszerzenie usługi , RoutingExtensionktóre zapewnia punkt ułatwień dostępu do modyfikowania konfiguracji usługi routingu w czasie wykonywania.

Klasa RoutingConfiguration zapewnia spójny sposób konfigurowania i aktualizowania konfiguracji usługi routingu. Zawiera parametry, które działają jako ustawienia usługi routingu i służy do konfigurowania routinguBehavior podczas uruchamiania usługi lub jest przekazywany do routinguExtension w celu modyfikowania konfiguracji routingu w czasie wykonywania.

Logika routingu używana do wykonywania routingu komunikatów opartych na zawartości jest definiowana przez grupowanie wielu MessageFilter obiektów w tabele filtrów (MessageFilterTable<TFilterData> obiekty). Komunikaty przychodzące są oceniane względem filtrów komunikatów zawartych w tabeli filtrów oraz dla każdego filtru MessageFilter zgodnego z komunikatem przesłanym dalej do docelowego punktu końcowego. Tabela filtrów, która powinna służyć do kierowania komunikatów, jest określana przy użyciu elementu RoutingBehavior w konfiguracji lub za pomocą kodu przy użyciu obiektu RoutingConfiguration .

Definiowanie punktów końcowych

Chociaż może się wydawać, że należy uruchomić konfigurację przez zdefiniowanie używanej logiki routingu, pierwszym krokiem powinno być określenie kształtu punktów końcowych, do których będą przekierowywane komunikaty. Usługa routingu używa kontraktów definiujących kształt kanałów używanych do odbierania i wysyłania komunikatów, a zatem kształt kanału wejściowego musi być zgodny z kształtem kanału wyjściowego. Jeśli na przykład kierujesz do punktów końcowych korzystających z kształtu kanału odpowiedzi żądania, musisz użyć zgodnego kontraktu w punktach końcowych przychodzących, takich jak IRequestReplyRouter.

Oznacza to, że jeśli docelowe punkty końcowe używają kontraktów z wieloma wzorcami komunikacji (takimi jak mieszanie operacji jednokierunkowych i dwukierunkowych), nie można utworzyć pojedynczego punktu końcowego usługi, który może odbierać i kierować komunikaty do wszystkich z nich. Należy określić, które punkty końcowe mają zgodne kształty i zdefiniować co najmniej jeden punkt końcowy usługi, który będzie używany do odbierania komunikatów do kierowania do docelowych punktów końcowych.

Uwaga

Podczas pracy z kontraktami, które określają wiele wzorców komunikacji (takich jak kombinacja operacji jednokierunkowych i dwukierunkowych), obejściem jest użycie kontraktu dwustronnego w usłudze routingu, takiego jak IDuplexSessionRouter. Oznacza to jednak, że powiązanie musi być w stanie komunikować się dwukierunkowo, co może nie być możliwe we wszystkich scenariuszach. W scenariuszach, w których nie jest to możliwe, może być konieczne uwzględnienie komunikacji w wielu punktach końcowych lub zmodyfikowanie aplikacji.

Aby uzyskać więcej informacji na temat kontraktów routingu, zobacz Routing Contracts (Kontrakty routingu).

Po zdefiniowaniu punktu końcowego usługi możesz użyć elementu RoutingBehavior , aby skojarzyć określoną konfigurację routingu z punktem końcowym. Podczas konfigurowania usługi routingu przy użyciu pliku konfiguracji element RoutingBehavior służy do określania tabeli filtrów zawierającej logikę routingu używaną do przetwarzania komunikatów odebranych w tym punkcie końcowym. Jeśli programowo konfigurujesz usługę routingu, możesz określić tabelę filtrów przy użyciu polecenia RoutingConfiguration.

W poniższym przykładzie zdefiniowano punkty końcowe usługi i klienta, które są używane przez usługę routingu programowo i przy użyciu pliku konfiguracji.

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

W tym przykładzie usługa routingu umożliwia skonfigurowanie usługi routingu w celu uwidocznienia pojedynczego punktu końcowego z adresem http://localhost:8000/routingservice/router, który służy do odbierania komunikatów do kierowania. Ponieważ komunikaty są kierowane do punktów końcowych odpowiedzi na żądanie, punkt końcowy usługi używa kontraktu IRequestReplyRouter . Ta konfiguracja definiuje również pojedynczy punkt końcowy klienta, http://localhost:8000/servicemodelsample/service do którego są kierowane komunikaty. Tabela filtrów (nie jest wyświetlana) o nazwie "routingTable1" zawiera logikę routingu używaną do kierowania komunikatów i jest skojarzona z punktem końcowym usługi przy użyciu elementu RoutingBehavior (dla pliku konfiguracji) lub RoutingConfiguration (dla konfiguracji programowej).

Logika routingu

Aby zdefiniować logikę routingu używaną do kierowania komunikatów, należy określić, jakie dane zawarte w komunikatach przychodzących mogą być jednoznacznie używane. Jeśli na przykład wszystkie docelowe punkty końcowe, które są kierowane do współużytkowania tych samych akcji protokołu SOAP, wartość akcji zawartej w komunikacie nie jest dobrym wskaźnikiem, do którego określony punkt końcowy powinien być kierowany komunikat. Jeśli musisz jednoznacznie kierować komunikaty do jednego określonego punktu końcowego, należy filtrować dane, które jednoznacznie identyfikują docelowy punkt końcowy, do którego jest kierowany komunikat.

Usługa routingu udostępnia kilka implementacji MessageFilter , które sprawdzają określone wartości w komunikacie, takie jak adres, akcja, nazwa punktu końcowego, a nawet zapytanie XPath. Jeśli żadna z tych implementacji nie spełnia Twoich potrzeb, możesz utworzyć niestandardową implementację MessageFilter . Aby uzyskać więcej informacji na temat filtrów komunikatów i porównania implementacji używanych przez usługę routingu, zobacz Filtry komunikatów i Wybieranie filtru.

Wiele filtrów komunikatów jest zorganizowanych razem w tabele filtrów, które kojarzą każdy filtr MessageFilter z docelowym punktem końcowym. Opcjonalnie tabelę filtrów można również użyć do określenia listy punktów końcowych kopii zapasowej, do których usługa routingu podejmie próbę wysłania komunikatu w przypadku awarii transmisji.

Domyślnie wszystkie filtry komunikatów w tabeli filtrów są oceniane jednocześnie; Można jednak określić element Priority , który powoduje, że filtry komunikatów mają być oceniane w określonej kolejności. Wszystkie wpisy z najwyższym priorytetem są oceniane jako pierwsze, a filtry komunikatów o niższych priorytetach nie są oceniane, jeśli dopasowanie zostanie znalezione na wyższym poziomie priorytetu. Aby uzyskać więcej informacji na temat tabel filtrów, zobacz Filtry komunikatów.

W poniższych przykładach użyto elementu MatchAllMessageFilter, który daje ocenę true dla wszystkich komunikatów. Ten filtr MessageFilter jest dodawany do tabeli filtrów "routingTable1", która kojarzy filtr MessageFilter z punktem końcowym klienta o nazwie "CalculatorService". Następnie routingBehavior określa, że ta tabela powinna być używana do kierowania komunikatów przetwarzanych przez punkt końcowy usługi.

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

Uwaga

Domyślnie usługa routingu ocenia tylko nagłówki komunikatu. Aby zezwolić filtrom na dostęp do treści komunikatu, należy ustawić wartość RouteOnHeadersOnlyfalse.

Multiemisji

Podczas gdy wiele konfiguracji usługi routingu używa logiki filtrowania wyłącznego, która kieruje komunikaty do tylko jednego określonego punktu końcowego, może być konieczne kierowanie danego komunikatu do wielu docelowych punktów końcowych. Aby multiemisji komunikat do wielu miejsc docelowych był spełniony, muszą być spełnione następujące warunki:

  • Kształt kanału nie może być odpowiedzią na żądanie (może być jednokierunkowy lub dwukierunkowy), ponieważ tylko jedna odpowiedź może zostać odebrana przez aplikację kliencą w odpowiedzi na żądanie.

  • Podczas oceniania komunikatu musi zostać zwróconych true wiele filtrów.

Jeśli te warunki zostaną spełnione, komunikat jest kierowany do wszystkich punktów końcowych wszystkich filtrów, które oceniają wartość .true W poniższym przykładzie zdefiniowano konfigurację routingu, która powoduje kierowanie komunikatów do obu punktów końcowych, jeśli adres punktu końcowego w komunikacie to 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);

Przetwarzanie protokołu SOAP

Aby obsługiwać routing komunikatów między różnymi protokołami, ustawienie RoutingBehavior domyślnie dodaje SoapProcessingBehavior element do wszystkich punktów końcowych klienta, do których są kierowane komunikaty. To zachowanie powoduje automatyczne utworzenie nowej wersji messageVersion przed przekierowaniem komunikatu do punktu końcowego, a także utworzenie zgodnej wersji komunikatu dla dowolnego dokumentu odpowiedzi przed zwróceniem go do żądanej aplikacji klienckiej.

Kroki wykonywane w celu utworzenia nowej wersji komunikatu wychodzącego są następujące:

Przetwarzanie żądań

  • Pobierz element MessageVersion powiązania/kanału wychodzącego.

  • Pobierz czytnik treści dla oryginalnej wiadomości.

  • Utwórz nowy komunikat z tą samą akcją, czytnikiem treści i nową wersją MessageVersion.

  • Jeśli Addressing != Adresowanie.None, skopiuj nagłówki To, From, FaultTo i RelatesTo do nowej wiadomości.

  • Skopiuj wszystkie właściwości komunikatu do nowej wiadomości.

  • Zapisz oryginalny komunikat żądania do użycia podczas przetwarzania odpowiedzi.

  • Zwróć nowy komunikat żądania.

Przetwarzanie odpowiedzi

  • Pobierz komunikat MessageVersion oryginalnego żądania.

  • Pobierz czytnik treści dla odebranych komunikatów odpowiedzi.

  • Utwórz nowy komunikat odpowiedzi z tą samą akcją, czytnikiem treści i elementem MessageVersion oryginalnego komunikatu żądania.

  • Jeśli Addressing != Adresowanie.None, skopiuj nagłówki To, From, FaultTo i RelatesTo do nowej wiadomości.

  • Skopiuj właściwości komunikatu do nowej wiadomości.

  • Zwróć nowy komunikat odpowiedzi.

Domyślnie element SoapProcessingBehavior jest automatycznie dodawany do punktów końcowych klienta przez RoutingBehavior czas uruchamiania usługi. Można jednak kontrolować, czy przetwarzanie protokołu SOAP jest dodawane do wszystkich punktów końcowych klienta przy użyciu SoapProcessingEnabled właściwości . Możesz również dodać zachowanie bezpośrednio do określonego punktu końcowego i włączyć lub wyłączyć to zachowanie na poziomie punktu końcowego, jeśli wymagana jest bardziej szczegółowa kontrola przetwarzania protokołu SOAP.

Uwaga

Jeśli przetwarzanie protokołu SOAP jest wyłączone dla punktu końcowego wymagającego innego komunikatu MessageVersion niż oryginalnego komunikatu żądania, należy podać niestandardowy mechanizm wykonywania wszelkich modyfikacji protokołu SOAP, które są wymagane przed wysłaniem komunikatu do docelowego punktu końcowego.

W poniższych przykładach właściwość soapProcessingEnabled służy do zapobiegania automatycznemu dodawaniu obiektu SoapProcessingBehavior do wszystkich punktów końcowych klienta.

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

Konfiguracja dynamiczna

Podczas dodawania dodatkowych punktów końcowych klienta lub konieczności zmodyfikowania filtrów używanych do kierowania komunikatów musisz mieć możliwość dynamicznego aktualizowania konfiguracji w czasie wykonywania, aby zapobiec przerwaniu działania usługi do punktów końcowych aktualnie odbierających komunikaty za pośrednictwem usługi routingu. Modyfikowanie pliku konfiguracji lub kodu aplikacji hosta nie zawsze jest wystarczające, ponieważ każda z metod wymaga odtworzenia aplikacji, co doprowadziłoby do potencjalnej utraty komunikatów aktualnie przesyłanych i potencjalnego przestoju podczas oczekiwania na ponowne uruchomienie usługi.

RoutingConfiguration można modyfikować tylko programowo. Chociaż początkowo można skonfigurować usługę przy użyciu pliku konfiguracji, można zmodyfikować konfigurację tylko w czasie wykonywania, tworząc nową konfigurację RoutingConfiguration i przekazując ją jako parametr do ApplyConfiguration metody uwidocznionej RoutingExtension przez rozszerzenie usługi. Wszystkie komunikaty, które są obecnie przesyłane, nadal są kierowane przy użyciu poprzedniej konfiguracji, podczas gdy komunikaty odebrane po wywołaniu metody ApplyConfiguration używają nowej konfiguracji. W poniższym przykładzie pokazano tworzenie wystąpienia usługi routingu, a następnie modyfikowanie konfiguracji.

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

Uwaga

Podczas aktualizowania usługi routingu w ten sposób możliwe jest tylko przekazanie nowej konfiguracji. Nie można modyfikować tylko elementów bieżącej konfiguracji lub dołączania nowych wpisów do bieżącej konfiguracji; Należy utworzyć i przekazać nową konfigurację, która zastępuje istniejącą.

Uwaga

Wszystkie sesje otwarte przy użyciu poprzedniej konfiguracji kontynuują korzystanie z poprzedniej konfiguracji. Nowa konfiguracja jest używana tylko przez nowe sesje.

Obsługa błędów

Jeśli wystąpi błąd CommunicationException podczas próby wysłania komunikatu, nastąpi obsługa błędów. Te wyjątki zwykle wskazują, że wystąpił problem podczas próby komunikowania się ze zdefiniowanym EndpointNotFoundExceptionpunktem końcowym klienta, takim jak , ServerTooBusyExceptionlub CommunicationObjectFaultedException. Kod obsługi błędów również przechwyci i spróbuje ponowić próbę wysłania, gdy TimeoutException wystąpi błąd, co jest innym typowym wyjątkiem, który nie pochodzi z klasy CommunicationException.

W przypadku wystąpienia jednego z powyższych wyjątków usługa routingu w trybie failover na liście punktów końcowych kopii zapasowych. Jeśli wszystkie punkty końcowe kopii zapasowej kończą się niepowodzeniem z powodu błędu komunikacji lub jeśli punkt końcowy zwróci wyjątek wskazujący błąd w usłudze docelowej, usługa routingu zwróci błąd aplikacji klienckiej.

Uwaga

Funkcja obsługi błędów przechwytuje i obsługuje wyjątki występujące podczas próby wysłania komunikatu i podczas próby zamknięcia kanału. Kod obsługi błędów nie jest przeznaczony do wykrywania lub obsługi wyjątków utworzonych przez punkty końcowe aplikacji, z których komunikuje się; w FaultException usłudze routingu jest wyświetlany komunikat o błędzie i jest przepływany z powrotem do klienta.

Jeśli wystąpi błąd, gdy usługa routingu próbuje przekazać komunikat, może zostać wyświetlony komunikat FaultException po stronie klienta, a nie EndpointNotFoundException w przypadku braku usługi routingu. Usługa routingu może w ten sposób maskowania wyjątków i nie zapewnia pełnej przejrzystości, chyba że zbadasz wyjątki zagnieżdżone.

Wyjątki śledzenia

Podczas wysyłania komunikatu do punktu końcowego na liście kończy się niepowodzeniem, usługa routingu śledzi wynikowe dane wyjątku i dołącza szczegóły wyjątku jako właściwość komunikatu o nazwie Wyjątki. Spowoduje to zachowanie danych wyjątku i umożliwia użytkownikowi programowy dostęp za pośrednictwem inspektora komunikatów. Dane wyjątku są przechowywane w słowniku, który mapuje nazwę punktu końcowego na szczegóły wyjątku napotkane podczas próby wysłania do niego komunikatu.

Punkty końcowe kopii zapasowej

Każdy wpis filtru w tabeli filtrów może opcjonalnie określić listę punktów końcowych kopii zapasowej, które są używane w przypadku awarii transmisji podczas wysyłania do podstawowego punktu końcowego. Jeśli wystąpi taka awaria, usługa routingu próbuje przesłać komunikat do pierwszego wpisu na liście punktów końcowych kopii zapasowej. Jeśli ta próba wysłania napotka również błąd transmisji, zostanie podjęta próba następnego punktu końcowego na liście kopii zapasowych. Usługa routingu kontynuuje wysyłanie komunikatu do każdego punktu końcowego na liście do momentu pomyślnego odebrania komunikatu, wszystkie punkty końcowe zwracają błąd transmisji lub awaria braku transmisji jest zwracana przez punkt końcowy.

W poniższych przykładach skonfigurowana jest usługa routingu tak, aby korzystała z listy kopii zapasowych.

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

Obsługiwane wzorce błędów

W poniższej tabeli opisano wzorce zgodne z użyciem list punktów końcowych kopii zapasowej oraz uwagi opisujące szczegóły obsługi błędów dla określonych wzorców.

Wzorzec Sesja Transakcja Kontekst odbierania Obsługiwana lista kopii zapasowych Uwagi
Komunikacja jednokierunkowa Tak Próbuje ponownie wysłać komunikat w punkcie końcowym kopii zapasowej. Jeśli ten komunikat jest multiemisji, tylko komunikat w kanale, który zakończył się niepowodzeniem, zostanie przeniesiony do miejsca docelowego kopii zapasowej.
Komunikacja jednokierunkowa ✔️ Nie. Zgłaszany jest wyjątek, a transakcja jest cofana.
Komunikacja jednokierunkowa ✔️ Tak Próbuje ponownie wysłać komunikat w punkcie końcowym kopii zapasowej. Po pomyślnym odebraniu komunikatu ukończ wszystkie konteksty odbierania. Jeśli komunikat nie zostanie pomyślnie odebrany przez żaden punkt końcowy, nie ukończ kontekstu odbierania.

Gdy ten komunikat jest multiemisji, kontekst odbierania jest wykonywany tylko wtedy, gdy komunikat zostanie pomyślnie odebrany przez co najmniej jeden punkt końcowy (podstawowy lub zapasowy). Jeśli żaden z punktów końcowych w żadnej ze ścieżek multiemisji pomyślnie otrzyma komunikat, nie ukończ kontekstu odbierania.
Komunikacja jednokierunkowa ✔️ ✔️ Tak Przerwij poprzednią transakcję, utwórz nową transakcję i wyślij ponownie wszystkie komunikaty. Komunikaty, które napotkały błąd, są przesyłane do miejsca docelowego kopii zapasowej.

Po utworzeniu transakcji, w której wszystkie transmisje zakończą się powodzeniem, ukończ konteksty odbierania i zatwierdź transakcję.
Komunikacja jednokierunkowa ✔️ Tak Próbuje ponownie wysłać komunikat w punkcie końcowym kopii zapasowej. W scenariuszu multiemisji tylko komunikaty w sesji, które napotkały błąd lub w sesji, której zamknięcie sesji nie powiodło się, są ponownie kopii zapasowej miejsc docelowych.
Komunikacja jednokierunkowa ✔️ ✔️ Nie. Zgłaszany jest wyjątek, a transakcja jest cofana.
Komunikacja jednokierunkowa ✔️ ✔️ Tak Próbuje ponownie wysłać komunikat w punkcie końcowym kopii zapasowej. Po zakończeniu wszystkich komunikatów bez błędu sesja wskazuje, że nie ma więcej komunikatów, a usługa routingu pomyślnie zamyka wszystkie kanały sesji wychodzących, wszystkie konteksty odbierania są ukończone, a kanał sesji przychodzącej jest zamknięty.
Komunikacja jednokierunkowa ✔️ ✔️ ✔️ Tak Przerwij bieżącą transakcję i utwórz nową. Wyślij ponownie wszystkie poprzednie komunikaty w sesji. Po utworzeniu transakcji, w której wszystkie komunikaty zostały pomyślnie wysłane, a sesja wskazuje, że nie ma więcej komunikatów, wszystkie kanały sesji wychodzącej są zamknięte, konteksty odbierania są zakończone z transakcją, kanał sesji przychodzącej jest zamykany, a transakcja zostaje zatwierdzona.

Gdy sesje są multiemisji komunikaty, które nie miały błędu, są ponownie wysyłane do tego samego miejsca docelowego co wcześniej, a komunikaty, które napotkały błąd, są wysyłane do miejsc docelowych kopii zapasowej.
Dwukierunkowe Tak Wyślij do miejsca docelowego kopii zapasowej. Gdy kanał zwróci komunikat odpowiedzi, zwróć odpowiedź na oryginalnego klienta.
Dwukierunkowe ✔️ Tak Wyślij wszystkie komunikaty w kanale do miejsca docelowego kopii zapasowej. Gdy kanał zwróci komunikat odpowiedzi, zwróć odpowiedź na oryginalnego klienta.
Dwukierunkowe ✔️ Nie. Zgłaszany jest wyjątek, a transakcja jest cofana.
Dwukierunkowe ✔️ ✔️ Nie. Zgłaszany jest wyjątek, a transakcja jest cofana.
Dupleks Nie. Komunikacja dwukierunkowa nie jest obecnie obsługiwana.
Dupleks ✔️ Tak Wyślij do miejsca docelowego kopii zapasowej.

Hosting

Ponieważ usługa routingu jest implementowana jako usługa WCF, musi być hostowana samodzielnie w aplikacji lub hostowanej przez usługi IIS lub WAS. Zaleca się, aby usługa routingu była hostowana w usługach IIS, WAS lub aplikacji usługi systemu Windows, aby korzystać z funkcji automatycznego uruchamiania i zarządzania cyklem życia dostępnych w tych środowiskach hostingu.

W poniższym przykładzie pokazano hostowanie usługi routingu w aplikacji.

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

Aby hostować usługę routingu w usługach IIS lub WAS, należy utworzyć plik usługi (.svc) lub użyć aktywacji opartej na konfiguracji usługi. W przypadku korzystania z pliku usługi należy określić RoutingService parametr Usługi. Poniższy przykład zawiera przykładowy plik usługi, który może służyć do hostowania usługi routingu za pomocą usług IIS lub WAS.

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

Usługa routingu i personifikacja

Usługa routingu WCF może być używana z personifikacją zarówno do wysyłania, jak i odbierania komunikatów. Obowiązują wszystkie typowe ograniczenia personifikacji systemu Windows. Jeśli konieczne byłoby skonfigurowanie uprawnień usługi lub konta do korzystania z personifikacji podczas pisania własnej usługi, musisz wykonać te same kroki, aby użyć personifikacji z usługą routingu. Aby uzyskać więcej informacji, zobacz Delegowanie i personifikacja.

Personifikacja w usłudze routingu wymaga użycia ASP.NET personifikacji w trybie zgodności ASP.NET lub używania poświadczeń systemu Windows skonfigurowanych do zezwalania na personifikację. Aby uzyskać więcej informacji na temat trybu zgodności ASP.NET, zobacz Usługi WCF i ASP.NET.

Ostrzeżenie

Usługa routingu WCF nie obsługuje personifikacji przy użyciu uwierzytelniania podstawowego.

Aby użyć ASP.NET personifikacji z usługą routingu, włącz tryb zgodności ASP.NET w środowisku hostingu usługi. Usługa routingu została już oznaczona jako zezwalająca na ASP.NET tryb zgodności i personifikacja zostanie automatycznie włączona. Personifikacja jest jedynym obsługiwanym użyciem integracji ASP.NET z usługą routingu.

Aby użyć personifikacji poświadczeń systemu Windows z usługą routingu, należy skonfigurować zarówno poświadczenia, jak i usługę. Obiekt poświadczeń klienta (WindowsClientCredentialdostępny z ChannelFactoryobiektu ) definiuje AllowedImpersonationLevel właściwość, która musi być ustawiona w celu zezwolenia na personifikację. Na koniec w usłudze należy skonfigurować ServiceAuthorizationBehavior zachowanie, aby ustawić wartość trueImpersonateCallerForAllOperations . Usługa routingu używa tej flagi, aby zdecydować, czy utworzyć klientów na potrzeby przekazywania komunikatów z włączonym personifikacją.

Zobacz też