Фильтры сообщений

Для реализации маршрутизации на основе содержимого служба маршрутизации использует MessageFilter реализации, которые проверяют определенные разделы сообщения, такие как адрес, имя конечной точки или конкретная инструкция XPath. Если ни один из фильтров сообщений, предоставляемых .NET Framework 4.6.1, не соответствует вашим потребностям, можно создать пользовательский фильтр, создав новую реализацию базового MessageFilter класса.

При настройке службы маршрутизации необходимо определить элементы фильтра (FilterElement объекты), описывающие тип MessageFilter и все вспомогательные данные, необходимые для создания фильтра, например определенные строковые значения для поиска в сообщении. Обратите внимание, что создание элементов фильтра определяет только отдельные фильтры сообщений; чтобы использовать фильтры для оценки и маршрутизации сообщений, необходимо также определить таблицу фильтров (FilterTableEntryCollection).

Каждая запись в таблице фильтров ссылается на элемент фильтра и указывает конечную точку клиента, в которую будет перенаправлено сообщение, если сообщение соответствует фильтру. Записи таблицы фильтров также позволяют указать коллекцию конечных точек резервного копирования (BackupEndpointCollection), которая определяет список конечных точек, в которые будет передано сообщение в случае сбоя передачи при отправке в основную конечную точку. Эти конечные точки будут проверены в указанном порядке до тех пор, пока не будет выполнено успешное действие.

Фильтры сообщений

Фильтры сообщений, используемые службой маршрутизации, предоставляют общие функции выбора сообщений, такие как оценка имени конечной точки, в которую было отправлено сообщение, действие SOAP или префикс адреса или адреса, в который было отправлено сообщение. Фильтры также можно объединить с AND условием, чтобы сообщения перенаправлялись только в конечную точку, если сообщение совпадает с обоими фильтрами. Вы также можете создавать пользовательские фильтры, создавая собственную реализацию MessageFilter.

В следующей таблице перечислены FilterType, которые используются службой маршрутизации, класс, реализующий конкретный фильтр сообщений, и необходимые параметры FilterData.

Тип фильтра Описание Значение фильтрации данных Пример фильтра
Действие ActionMessageFilter Использует класс для сопоставления сообщений, содержащих определенное действие. Действие, по которому выполняется фильтрация. <filter name="action1" filterType="Action" filterData="http://namespace/contract/operation" />
Адрес конечной точки Класс EndpointAddressMessageFilter используется с IncludeHostNameInComparison == true для сопоставления сообщений, содержащих определенный адрес. Адрес для фильтрации (в заголовке To). <filter name="address1" filterType="EndpointAddress" filterData="http://host/vdir/s.svc/b" />
ПрефиксАдресаКонечнойТочки PrefixEndpointAddressMessageFilter Использует класс для IncludeHostNameInComparison == true сопоставления сообщений, содержащих определенный префикс адреса. Адрес для фильтрации с использованием наиболее длинного совпадения префикса. <filter name="prefix1" filterType="EndpointAddressPrefix" filterData="http://host/" />
И StrictAndMessageFilter Использует класс, который всегда вычисляет оба условия перед возвратом. filterData не используется; Вместо этого filter1 и filter2 имеют имена соответствующих фильтров сообщений (также в таблице), которые должны бытьобъединены вместе. <filter name="and1" filterType="And" filter1="address1" filter2="action1" />
Обычай Тип, определяемый пользователем, который расширяет класс MessageFilter и имеет конструктор, принимающий строку. Атрибут customType — это полное имя типа создаваемого класса; filterData — это строка, передаваемая конструктору при создании фильтра. <filter name="custom1" filterType="Custom" customType="CustomAssembly.CustomMsgFilter, CustomAssembly" filterData="Custom Data" />
Имя конечной точки Класс EndpointNameMessageFilter используется для сопоставления сообщений на основе имени конечной точки службы, через которую они прибыли. Имя конечной точки службы, например serviceEndpoint1. Это должна быть одна из конечных точек, предоставляемых в службе маршрутизации. <filter name="stock1" filterType="Endpoint" filterData="SvcEndpoint" />
MatchAll Класс MatchAllMessageFilter используется. Этот фильтр соответствует всем поступающим сообщениям. filterData не используется. Этот фильтр всегда будет соответствовать всем сообщениям. <filter name="matchAll1" filterType="MatchAll" />
XPath XPathMessageFilter Использует класс для сопоставления определенных запросов XPath в сообщении. Запрос XPath, используемый при сопоставлении сообщений. <filter name="XPath1" filterType="XPath" filterData="//ns:element" />

В следующем примере определяются записи фильтра, использующие фильтры сообщений XPath, EndpointName и PrefixEndpointAddress. В этом примере также демонстрируется использование пользовательского фильтра для записей RoundRobinFilter1 и 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>

Замечание

Простое определение фильтра не приводит к оценке сообщений по фильтру. Фильтр необходимо добавить в таблицу фильтров, которая затем связана с конечной точкой службы, предоставляемой службой маршрутизации.

Таблица пространства имен

При использовании фильтра XPath данные фильтра, содержащие запрос XPath, могут стать чрезвычайно большими из-за использования пространств имен. Чтобы устранить эту проблему, служба маршрутизации предоставляет возможность определять префиксы собственного пространства имен с помощью таблицы пространства имен.

Таблица пространства имен — это коллекция NamespaceElement объектов, определяющих префиксы пространства имен для общих пространств имен, которые можно использовать в XPath. Ниже перечислены пространства имен по умолчанию и префиксы пространства имен, содержащиеся в таблице пространства имен.

Приставка Пространство имен
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
Сир http://schemas.microsoft.com/2003/10/Serialization

Если вы знаете, что вы будете использовать определенное пространство имен в запросах XPath, его можно добавить в таблицу пространства имен вместе с префиксом уникального пространства имен и использовать префикс в любом запросе XPath вместо полного пространства имен. В следующем примере определяется префикс "custom" для пространства имен "http://my.custom.namespace", который затем используется в запросе XPath, содержащемся в 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>

Фильтрация таблиц

Хотя каждый элемент фильтра определяет логическое сравнение, которое можно применить к сообщению, таблица фильтров обеспечивает связь между элементом фильтра и конечной точкой целевого клиента. Таблица фильтров — это именованная коллекция объектов, определяющих FilterTableEntryElement связь между фильтром, основной конечной точкой назначения и списком альтернативных конечных точек резервного копирования. Записи таблицы фильтров также позволяют указать необязательный приоритет для каждого условия фильтра. В следующем примере определяются два фильтра, а затем определяется таблица фильтров, которая связывает каждый фильтр с конечной точкой назначения.

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

Приоритет оценки фильтра

По умолчанию все записи в таблице фильтров оцениваются одновременно, а вычисляемое сообщение направляется в конечные точки, связанные с каждой записью соответствующего фильтра. Если несколько фильтров оцениваются в true, и если сообщение является одно-сторонним или дуплексным, то сообщение рассылается конечным точкам для всех соответствующих фильтров. Сообщения типа "запрос-ответ" не могут быть многоадресной рассылкой, так как можно вернуть клиенту только единственный ответ.

Более сложная логика маршрутизации может быть реализована путем указания уровней приоритета для каждого фильтра; Служба маршрутизации сначала оценивает все фильтры на самом высоком уровне приоритета. Если сообщение соответствует фильтру этого уровня, то не обрабатываются фильтры более низкого приоритета. Например, входящее односторонное сообщение сначала вычисляется по всем фильтрам с приоритетом 2. Сообщение не соответствует ни одному фильтру на этом уровне приоритета, поэтому следующее сообщение сравнивается с фильтрами с приоритетом 1. Два фильтра приоритета 1 соответствуют этому сообщению, и, поскольку это одностороннее сообщение, оно отправляется в обе конечные точки назначения. Поскольку совпадение обнаружено среди фильтров приоритета 1, фильтры приоритета 0 не оцениваются.

Замечание

Если приоритет не указан, используется приоритет по умолчанию 0.

В следующем примере определяется таблица фильтров, указывающая приоритеты 2, 1 и 0 для фильтров, на которые ссылается таблица.

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

В предыдущем примере, если сообщение соответствует XPathFilter, оно будет перенаправлено в roundingCalcEndpoint, и никакие другие фильтры в таблице не будут оцениваться, так как все остальные фильтры имеют более низкий приоритет. Однако если сообщение не соответствует XPathFilter, оно будет оцениваться по всем фильтрам следующего нижнего приоритета, EndpointNameFilter и PrefixAddressFilter.

Замечание

По возможности используйте эксклюзивные фильтры вместо указания приоритета, так как оценка приоритета может привести к снижению производительности.

Списки резервных копий

Каждый фильтр в таблице фильтров может дополнительно указать список резервных копий, который является именованной коллекцией конечных точек (BackupEndpointCollection). Эта коллекция содержит упорядоченный список конечных точек, на которые будет передано сообщение в случае CommunicationException отправки в основную конечную точку, указанную в EndpointName. В следующем примере определяется список резервных копий с именем BackupServiceEndpoints, содержащий две конечные точки.

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

В предыдущем примере, если отправка в основную конечную точку "Назначение" завершается ошибкой, служба маршрутизации попытается отправить на каждую конечную точку по порядку. Сначала она отправит в "ОчередьРезервнойСлужбы", а если это завершится неудачей, предпримет попытку отправки в "ОчередьАльтернативнойСлужбы". Если все резервные узлы не срабатывают, возвращается ошибка.