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

  1. 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).

  2. Aby uruchomić przykład w konfiguracji pojedynczej maszyny, postępuj zgodnie z instrukcjami w temacie Uruchamianie przykładów programu Windows Communication Foundation.

  3. 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");