Niestandardowy filtr komunikatów
W przykładzie MessageFilter pokazano, jak zastąpić filtry komunikatów używane przez program Windows Communication Foundation (WCF) do wysyłania komunikatów do punktów końcowych.
Uwaga
Procedura instalacji i instrukcje kompilacji dla tego przykładu znajdują się na końcu tego tematu.
Gdy pierwszy komunikat w kanale pojawi się na serwerze, serwer musi określić, które (jeśli istnieją) punktów końcowych skojarzonych z tym identyfikatorem URI, powinny otrzymać komunikat. Ten proces jest kontrolowany MessageFilter przez obiekty dołączone do obiektu EndpointDispatcher.
Każdy punkt końcowy usługi ma jeden EndpointDispatcherelement . Obiekt EndpointDispatcher ma zarówno element , jak ContractFilterAddressFilter i . Połączenie tych dwóch filtrów to filtr komunikatu używany dla tego punktu końcowego.
Domyślnie dla AddressFilter punktu końcowego pasuje do dowolnego komunikatu, który jest adresowany do adresu zgodnego z punktem końcowym EndpointAddressusługi . Domyślnie ContractFilter dla punktu końcowego sprawdza akcję komunikatu przychodzącego i pasuje do dowolnego komunikatu z akcją odpowiadającą jednej z akcji operacji kontraktu punktu końcowego usługi (są brane pod uwagę tylko IsInitiating
=true
akcje). W związku z tym domyślnie filtr dla punktu końcowego jest zgodny tylko wtedy, gdy nagłówek Do komunikatu jest EndpointAddress punktem końcowym, a akcja komunikatu jest zgodna z jedną z akcji operacji punktu końcowego.
Te filtry można zmienić przy użyciu zachowania. W przykładzie usługa tworzy obiekt IEndpointBehavior , który zastępuje element AddressFilter i ContractFilter w elemencie EndpointDispatcher:
class FilteringEndpointBehavior : IEndpointBehavior
{
//...
}
Zdefiniowano dwa filtry adresów:
// 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 { }
Element FilteringEndpointBehavior
jest konfigurowalny i umożliwia korzystanie z dwóch różnych odmian.
public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement { }
Odmiana 1 pasuje tylko do adresów zawierających "e" (ale które mają dowolną akcję), podczas gdy odmiana 2 pasuje tylko do adresów, które nie mają znaku "e":
if (Variation == 1)
return new FilteringEndpointBehavior(
new MatchEAddressFilter(), new MatchAllMessageFilter());
else
return new FilteringEndpointBehavior(
new MatchNoEAddressFilter(), new MatchAllMessageFilter());
W pliku konfiguracji usługa rejestruje nowe zachowanie:
<extensions>
<behaviorExtensions>
<add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
</behaviorExtensions>
</extensions>
Następnie usługa tworzy endpointBehavior
konfiguracje dla każdej odmiany:
<endpointBehaviors>
<behavior name="endpoint1">
<filteringEndpointBehavior variation="1" />
</behavior>
<behavior name="endpoint2">
<filteringEndpointBehavior variation="2" />
</behavior>
</endpointBehaviors>
Na koniec punkt końcowy usługi odwołuje się do jednego z następujących elementów behaviorConfigurations
:
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint2" />
Implementacja aplikacji klienckiej jest prosta; Tworzy dwa kanały do identyfikatora URI usługi (przekazując ją jako drugi parametr (via
) do CreateChannel(EndpointAddress) i wysyłając jeden komunikat w każdym kanale, ale używa różnych adresów punktów końcowych dla każdego z nich. W związku z tym komunikaty wychodzące od klienta mają inne oznaczenia Do, a serwer odpowiada odpowiednio, jak pokazano w danych wyjściowych klienta:
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
Przełączenie odmiany w pliku konfiguracji serwera powoduje zamianę filtru, a klient widzi odwrotne zachowanie (komunikat powiedzie urn:e
się, podczas gdy komunikat kończy się urn:a
niepowodzeniem).
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint1" />
Aby skonfigurować, skompilować i uruchomić przykład
Aby skompilować rozwiązanie, postępuj zgodnie z instrukcjami w temacie Building the Windows Communication Foundation Samples (Tworzenie przykładów programu Windows Communication Foundation).
Aby uruchomić przykład w konfiguracji pojedynczej maszyny, postępuj zgodnie z instrukcjami w temacie Uruchamianie przykładów programu Windows Communication Foundation.
Aby uruchomić przykład w konfiguracji między maszynami, postępuj zgodnie z instrukcjami w artykule Uruchamianie przykładów programu Windows Communication Foundation i zmień następujący wiersz w Client.cs.
Uri serviceVia = new Uri("http://localhost/ServiceModelSamples/service.svc");
Zastąp ciąg localhost nazwą serwera.
Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");