Пользовательский фильтр сообщений
В этом образце показано, как заменить фильтры сообщений, используемые в Windows Communication Foundation (WCF) для перенаправления сообщений в конечные точки.
![]() |
---|
Процедура настройки и инструкции по построению для данного образца приведены в конце этого раздела. |
При поступлении на сервер первого сообщения из канала сервер должен определить, какие конечные точки, связанные с данным URI, должны получить сообщение. Этот процесс контролируется объектами MessageFilter присоединенными к диспетчеру EndpointDispatcher.
У каждой конечной точки службы имеется один диспетчер EndpointDispatcher. У диспетчера EndpointDispatcher имеются как фильтр AddressFilter, так и фильтр ContractFilter. Объединение этих двух фильтров является фильтром сообщений, используемым для данной конечной точки.
По умолчанию фильтр AddressFilter для конечной точки соответствует любому сообщению, передаваемому по адресу, который соответствует адресу EndpointAddress конечной точки службы. По умолчанию фильтр ContractFilter для конечной точки проверяет действие входящего сообщения и сопоставляет любое сообщение с действием, соответствующим одному из действий операций контракта конечной точки службы (рассматриваются только действия IsInitiating=true). В результате по умолчанию соответствие фильтру для конечной точки обеспечивается, только если в заголовках "To" обоих сообщений задан адрес EndpointAddress конечной точки и действие сообщения соответствует одному из действий операции конечной точки.
Эти фильтры можно изменить с помощью поведения. В этом образце служба создает интерфейс IEndpointBehavior, который заменяет фильтры AddressFilter и ContractFilter в диспетчере EndpointDispatcher:
class FilteringEndpointBehavior : IEndpointBehavior …
Определяется два фильтра адресов:
// Matches any message whose To address contains the letter 'e'
class MatchEAddressFilter : MessageFilter …
// Matches any message whose To address does not contain the letter 'e'
class MatchNoEAddressFilter : MessageFilter
Поведение FilteringEndpointBehavior
делается настраиваемым и предусматривает два различных варианта.
public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement
Вариант 1 соответствует только адресам, в которых содержится буква 'e' (и которые имеют любое действие), а вариант 2 соответствует только адресам, в которых отсутствует буква 'e':
if (Variation == 1)
return new FilteringEndpointBehavior(
new MatchEAddressFilter(), new MatchAllMessageFilter());
else
return new FilteringEndpointBehavior(
new MatchNoEAddressFilter(), new MatchAllMessageFilter());
В файле конфигурации служба регистрирует новое поведение:
<extensions>
<behaviorExtensions>
<add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
</behaviorExtensions>
</extensions>
Затем служба создает конфигурации endpointBehavior для каждого варианта:
<endpointBehaviors>
<behavior name="endpoint1">
<filteringEndpointBehavior variation="1" />
</behavior>
<behavior name="endpoint2">
<filteringEndpointBehavior variation="2" />
</behavior>
</endpointBehaviors>
Наконец, конечная точка службы ссылается на одну из конфигураций behaviorConfigurations
:
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint2" />
Реализация клиентского приложения является прямолинейной; она создает два канала к URI службы (передавая заданное значение в качестве второго параметра (via) методу CreateChannel) и отправляет одно сообщение по каждому каналу, но использует в каждом случае различные адреса конечной точки. В результате исходящие сообщения клиента имеют разные адреса назначения в поле "To" и сервер реагирует соответствующим образом, как показано в выходных данных клиента:
Sending message to urn:e...
Exception: The message with To 'urn:e' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.
Sending message to urn:a...
Hello
Переключение варианта в файле конфигурации сервера приводит к перестановке фильтров, и на клиенте наблюдается противоположное поведение (доставка сообщения по адресу urn:e
является успешной, а доставка сообщения по адресу urn:a
— неудачной).
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint1" />
![]() |
---|
Образцы уже могут быть установлены на компьютере. Перед продолжением проверьте следующий каталог (по умолчанию).
<диск_установки>:\WF_WCF_Samples
Если этот каталог не существует, перейдите на страницу Образцы Windows Communication Foundation (WCF) и Windows Workflow Foundation (WF) для .NET Framework 4, чтобы загрузить все образцы Windows Communication Foundation (WCF) и WF. Этот образец расположен в следующем каталоге.
<диск_установки>:\WF_WCF_Samples\WCF\Extensibility\MessageFilter
|
Настройка, построение и выполнение образца
Чтобы построить решение, следуйте инструкциям в разделе Построение образцов Windows Communication Foundation.
Чтобы выполнить образец на одном компьютере, следуйте инструкциям раздела Running the Windows Communication Foundation Samples.
Чтобы выполнить образец на нескольких компьютерах, выполните инструкции в разделе Running the Windows Communication Foundation Samples и измените следующую строку в файле Client.cs.
Uri serviceVia = new Uri("https://localhost/ServiceModelSamples/service.svc");
Замените localhost именем сервера.
Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");