Filtry komunikatów
Aby zaimplementować routing oparty na zawartości, usługa routingu używa MessageFilter implementacji, które sprawdzają określone sekcje komunikatu, takie jak adres, nazwa punktu końcowego lub konkretna instrukcja XPath. Jeśli żaden z filtrów komunikatów dostarczonych z programem .NET Framework 4.6.1 nie spełnia Twoich potrzeb, możesz utworzyć niestandardowy filtr, tworząc nową implementację klasy bazowej MessageFilter .
Podczas konfigurowania usługi routingu należy zdefiniować elementy filtru (FilterElement obiekty), które opisują typ messageFilter i wszelkie dane pomocnicze wymagane do utworzenia filtru, takie jak określone wartości ciągu do wyszukania w wiadomości. Należy pamiętać, że tworzenie elementów filtru definiuje tylko poszczególne filtry komunikatów; aby użyć filtrów do oceny i kierowania komunikatów, należy również zdefiniować tabelę filtrów (FilterTableEntryCollection).
Każdy wpis w tabeli filtrów odwołuje się do elementu filtru i określa punkt końcowy klienta, do którego będzie kierowany komunikat, jeśli komunikat jest zgodny z filtrem. Wpisy tabeli filtru umożliwiają również określenie kolekcji punktów końcowych kopii zapasowej (BackupEndpointCollection), która definiuje listę punktów końcowych, do których komunikat zostanie przesłany w przypadku niepowodzenia transmisji podczas wysyłania do podstawowego punktu końcowego. Te punkty końcowe zostaną wypróbowane w określonej kolejności, dopóki nie powiedzie się.
Filtry komunikatów
Filtry komunikatów używane przez usługę routingu zapewniają typowe funkcje wyboru komunikatów, takie jak ocena nazwy punktu końcowego, do którego wysłano komunikat, akcja PROTOKOŁU SOAP lub adres lub prefiks adresu, do którego wysłano komunikat. Filtry można również łączyć z AND
warunkiem, dzięki czemu komunikaty będą kierowane tylko do punktu końcowego, jeśli komunikat pasuje do obu filtrów. Możesz również utworzyć filtry niestandardowe, tworząc własną implementację programu MessageFilter.
Poniższa tabela zawiera listę FilterType używanych przez usługę routingu, klasę, która implementuje określony filtr komunikatów i wymagane FilterData parametry.
Typ filtru | Opis | Znaczenie filtru danych | Przykładowy filtr |
---|---|---|---|
Akcja | ActionMessageFilter Używa klasy do dopasowywania komunikatów zawierających określoną akcję. | Akcja do filtrowania. | <filter name="action1" filterType="Action" filterData="http://namespace/contract/operation" /> |
Endpointaddress | EndpointAddressMessageFilter Używa klasy z elementem IncludeHostNameInComparison == true , aby dopasować komunikaty zawierające określony adres. |
Adres do filtrowania (w nagłówku Do). | <filter name="address1" filterType="EndpointAddress" filterData="http://host/vdir/s.svc/b" /> |
EndpointAddressPrefix | PrefixEndpointAddressMessageFilter Używa klasy z elementem IncludeHostNameInComparison == true , aby dopasować komunikaty zawierające określony prefiks adresu. |
Adres do filtrowania przy użyciu najdłuższego dopasowania prefiksu. | <filter name="prefix1" filterType="EndpointAddressPrefix" filterData="http://host/" /> |
And | StrictAndMessageFilter Używa klasy, która zawsze ocenia oba warunki przed zwróceniem. | filterData nie jest używana; Zamiast tego filter1 i filter2 mają nazwy odpowiednich filtrów komunikatów (również w tabeli), które powinny być ipołączone. | <filter name="and1" filterType="And" filter1="address1" filter2="action1" /> |
Niestandardowy | Typ zdefiniowany przez użytkownika, który rozszerza MessageFilter klasę i ma konstruktor biorący ciąg. | Atrybut customType jest w pełni kwalifikowaną nazwą typu klasy do utworzenia; filterData to ciąg przekazywany do konstruktora podczas tworzenia filtru. | <filter name="custom1" filterType="Custom" customType="CustomAssembly.CustomMsgFilter, CustomAssembly" filterData="Custom Data" /> |
Nazwa punktu końcowego | EndpointNameMessageFilter Używa klasy do dopasowywania komunikatów na podstawie nazwy punktu końcowego usługi, do którego dotarł. | Nazwa punktu końcowego usługi, na przykład: "serviceEndpoint1". Powinien to być jeden z punktów końcowych uwidocznionych w usłudze routingu. | <filter name="stock1" filterType="Endpoint" filterData="SvcEndpoint" /> |
MatchAll | MatchAllMessageFilter Używa klasy . Ten filtr pasuje do wszystkich przychodzących komunikatów. | filterData nie jest używana. Ten filtr będzie zawsze zgodny ze wszystkimi komunikatami. | <filter name="matchAll1" filterType="MatchAll" /> |
XPath | XPathMessageFilter Używa klasy do dopasowania określonych zapytań XPath w komunikacie. | Zapytanie XPath do użycia podczas dopasowywania komunikatów. | <filter name="XPath1" filterType="XPath" filterData="//ns:element" /> |
W poniższym przykładzie zdefiniowano wpisy filtru, które używają filtrów komunikatów XPath, EndpointName i PrefixEndpointAddress. W tym przykładzie pokazano również użycie niestandardowego filtru dla wpisów RoundRobinFilter1 i RoundRobinFilter2.
<filters>
<filter name="XPathFilter" filterType="XPath"
filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>
<filter name="EndpointNameFilter" filterType="EndpointName"
filterData="calculatorEndpoint"/>
<filter name="PrefixAddressFilter" filterType="PrefixEndpointAddress"
filterData="http://localhost/routingservice/router/rounding/"/>
<filter name="RoundRobinFilter1" filterType="Custom"
customType="RoutingServiceFilters.RoundRobinMessageFilter,
RoutingService" filterData="group1"/>
<filter name="RoundRobinFilter2" filterType="Custom"
customType="RoutingServiceFilters.RoundRobinMessageFilter,
RoutingService" filterData="group1"/>
</filters>
Uwaga
Po prostu zdefiniowanie filtru nie powoduje oceny komunikatów względem filtru. Filtr należy dodać do tabeli filtrów, która jest następnie skojarzona z punktem końcowym usługi uwidocznionym przez usługę routingu.
Tabela przestrzeni nazw
W przypadku korzystania z filtru XPath dane filtru zawierające zapytanie XPath mogą stać się bardzo duże ze względu na użycie przestrzeni nazw. Aby złagodzić ten problem, usługa routingu umożliwia definiowanie własnych prefiksów przestrzeni nazw przy użyciu tabeli przestrzeni nazw.
Tabela przestrzeni nazw jest kolekcją NamespaceElement obiektów definiujących prefiksy przestrzeni nazw dla typowych przestrzeni nazw, które mogą być używane w programie XPath. Poniżej przedstawiono domyślne przestrzenie nazw i prefiksy przestrzeni nazw, które znajdują się w tabeli przestrzeni nazw.
Prefiks | Przestrzeń nazw |
---|---|
s11 | http://schemas.xmlsoap.org/soap/envelope |
s12 | http://www.w3.org/2003/05/soap-envelope |
wsaAugust2004 | http://schemas.xmlsoap.org/ws/2004/08/addressing |
wsa10 | http://www.w3.org/2005/08/addressing |
sm | http://schemas.microsoft.com/serviceModel/2004/05/xpathfunctions |
tempuri | http://tempuri.org |
ser | http://schemas.microsoft.com/2003/10/Serialization |
Jeśli wiesz, że będziesz używać określonej przestrzeni nazw w zapytaniach XPath, możesz dodać ją do tabeli przestrzeni nazw wraz z unikatowym prefiksem przestrzeni nazw i użyć prefiksu w dowolnym zapytaniu XPath zamiast pełnej przestrzeni nazw. W poniższym przykładzie zdefiniowano prefiks "niestandardowy" dla przestrzeni nazw "http://my.custom.namespace"
, która jest następnie używana w zapytaniu XPath zawartym w filterData.
<namespaceTable>
<add prefix="custom" namespace="http://my.custom.namespace/"/>
</namespaceTable>
<filters>
<filter name="XPathFilter" filterType="XPath" filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>
</filters>
Filtrowanie tabel
Podczas gdy każdy element filtru definiuje porównanie logiczne, które można zastosować do komunikatu, tabela filtrów udostępnia skojarzenie między elementem filtru a docelowym punktem końcowym klienta. Tabela filtrów FilterTableEntryElement to nazwana kolekcja obiektów, które definiują skojarzenie między filtrem, podstawowym punktem końcowym docelowym i listą alternatywnych punktów końcowych kopii zapasowej. Wpisy tabeli filtru umożliwiają również określenie opcjonalnego priorytetu dla każdego warunku filtru. W poniższym przykładzie zdefiniowano dwa filtry, a następnie zdefiniowano tabelę filtrów, która kojarzy każdy filtr z docelowym punktem końcowym.
<routing>
<filters>
<filter name="AddAction" filterType="Action" filterData="Add" />
<filter name="SubtractAction" filterType="Action" filterData="Subtract" />
</filters>
<filterTables>
<table name="routingTable1">
<filters>
<add filterName="AddAction" endpointName="Addition" />
<add filterName="SubtractAction" endpointName="Subtraction" />
</filters>
</table>
</filterTables>
</routing>
Priorytet oceny filtru
Domyślnie wszystkie wpisy w tabeli filtrów są oceniane jednocześnie, a szacowany komunikat jest kierowany do punktów końcowych skojarzonych z każdym pasującym wpisem filtru. Jeśli wiele filtrów ocenia wartość true
, a komunikat jest jednokierunkowy lub dwukierunkowy, komunikat jest multiemisji do punktów końcowych dla wszystkich pasujących filtrów. Wiadomości odpowiedzi na żądanie nie mogą być multiemisji, ponieważ do klienta może zostać zwrócona tylko jedna odpowiedź.
Bardziej złożoną logikę routingu można zaimplementować, określając poziomy priorytetów dla każdego filtru; Usługa routingu najpierw ocenia wszystkie filtry na najwyższym poziomie priorytetu. Jeśli komunikat pasuje do filtru tego poziomu, żadne filtry o niższym priorytcie nie są przetwarzane. Na przykład przychodzący jednokierunkowy komunikat jest najpierw oceniany względem wszystkich filtrów z priorytetem 2. Komunikat nie jest zgodny z żadnym filtrem na tym poziomie priorytetu, więc następny komunikat jest porównywany z filtrami z priorytetem 1. Dwa filtry o priorytecie 1 są zgodne z komunikatem i ponieważ jest to komunikat jednokierunkowy, jest kierowany do obu docelowych punktów końcowych. Ponieważ wśród filtrów priorytetu 1 znaleziono dopasowanie, nie są oceniane filtry priorytetu 0.
Uwaga
Jeśli nie określono priorytetu, używany jest domyślny priorytet 0.
W poniższym przykładzie zdefiniowano tabelę filtrów, która określa priorytety 2, 1 i 0 dla filtrów, do których odwołuje się tabela.
<filterTables>
<filterTable name="filterTable1">
<add filterName="XPathFilter" endpointName="roundingCalcEndpoint"
priority="2"/>
<add filterName="EndpointNameFilter" endpointName="regularCalcEndpoint"
priority="1"/>
<add filterName="PrefixAddressFilter" endpointName="roundingCalcEndpoint"
priority="1"/>
<add filterName="MatchAllMessageFilter" endpointName="defaultCalcEndpoint"
priority="0"/>
</filterTable>
</filterTables>
W poprzednim przykładzie, jeśli komunikat pasuje do filtru XPathFilter, zostanie skierowany do zaokrąglaniaCalcEndpoint i nie zostaną ocenione żadne dalsze filtry w tabeli, ponieważ wszystkie inne filtry mają niższy priorytet. Jeśli jednak komunikat nie jest zgodny z filtrem XPathFilter, zostanie oceniony względem wszystkich filtrów następnego niższego priorytetu, EndpointNameFilter i PrefixAddressFilter.
Uwaga
Jeśli to możliwe, użyj filtrów wyłącznych zamiast określania priorytetu, ponieważ ocena priorytetu może spowodować obniżenie wydajności.
Listy kopii zapasowych
Każdy filtr w tabeli filtrów może opcjonalnie określić listę kopii zapasowych, która jest nazwaną kolekcją punktów końcowych (BackupEndpointCollection). Ta kolekcja zawiera uporządkowaną listę punktów końcowych, do których komunikat zostanie przesłany w przypadku CommunicationException wysyłania do podstawowego punktu końcowego określonego w EndpointNameelem. W poniższym przykładzie zdefiniowano listę kopii zapasowych o nazwie "backupServiceEndpoints", która zawiera dwa punkty końcowe.
<filterTables>
<filterTable name="filterTable1">
<add filterName="MatchAllFilter1" endpointName="Destination" backupList="backupEndpointList"/>
</filterTable>
</filterTables>
<backupLists>
<backupList name="backupEndpointList">
<add endpointName="backupServiceQueue" />
<add endpointName="alternateServiceQueue" />
</backupList>
</backupLists>
W poprzednim przykładzie, jeśli wysłanie do podstawowego punktu końcowego "Destination" zakończy się niepowodzeniem, usługa routingu spróbuje wysłać do każdego punktu końcowego w podanej kolejności, najpierw wysyłając do elementu backupServiceQueue, a następnie wysyłając do alternatywnego kolejkiServiceQueue, jeśli wysyłanie do kopii zapasowejServiceQueue zakończy się niepowodzeniem. Jeśli wszystkie punkty końcowe kopii zapasowej nie powiedzą się, zostanie zwrócony błąd.