Benutzerdefinierter Nachrichtenfilter

In diesem Beispiel wird gezeigt, wie die Nachrichtenfilter ersetzt werden, mit denen Windows Communication Foundation (WCF) Nachrichten auf Endpunkte verteilt.

Tipp

Die Setupprozedur und die Erstellungsanweisungen für dieses Beispiel befinden sich am Ende dieses Themas.

Wenn die erste Nachricht auf einem Kanal beim Server eintrifft, muss der Server bestimmen, welcher der mit diesem URI verknüpften Endpunkte (sofern zutreffend) die Nachricht erhalten soll. Dieser Prozess wird von den an den EndpointDispatcher angefügten MessageFilter-Objekten kontrolliert.

Jeder Endpunkt eines Diensts hat einen einzelnen EndpointDispatcher. Der EndpointDispatcher besitzt sowohl einen AddressFilter als auch einen ContractFilter. Die Verbindung dieser beiden Filter ist der für diesen Endpunkt verwendete Nachrichtenfilter.

Standardmäßig stimmt der AddressFilter für einen Endpunkt mit jeder Nachricht überein, die an eine Adresse gesendet wird, die wiederum mit der EndpointAddress des Dienstendpunkts übereinstimmt. Der ContractFilter für einen Endpunkt überprüft standardmäßig die Aktion der eingehenden Nachricht und gleicht jede Nachricht mit einer Aktion ab, die einer der Aktionen der Vorgänge des Dienstendpunktvertrags entspricht (es werden nur IsInitiating=true-Aktionen berücksichtigt). Demzufolge stimmt der Filter für einen Endpunkt standardmäßig nur überein, wenn sowohl der To-Header der Nachricht die EndpointAddress des Endpunkts ist als auch die Aktion der Nachricht mit einer der Aktionen der Endpunktvorgänge übereinstimmt.

Diese Filter können mit einer Verhaltensweise geändert werden. Im folgenden Beispiel erstellt der Dienst ein IEndpointBehavior, das den AddressFilter und den ContractFilter auf dem EndpointDispatcher ersetzt:

class FilteringEndpointBehavior : IEndpointBehavior …

Es werden zwei Adressfilter definiert:

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

Das FilteringEndpointBehavior wird konfigurierbar gemacht und ermöglicht zwei verschiedene Varianten.

public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement

Variante 1 gleicht nur Adressen ab, die ein "e" (aber eine beliebige Aktion) enthalten, wohingegen Variante 2 nur die Adressen ohne "e" abgleicht:

if (Variation == 1)
    return new FilteringEndpointBehavior(
        new MatchEAddressFilter(), new MatchAllMessageFilter());
else
    return new FilteringEndpointBehavior(
        new MatchNoEAddressFilter(), new MatchAllMessageFilter());

Der Dienst registriert das neue Verhalten in der Konfigurationsdatei:

<extensions>
    <behaviorExtensions>
        <add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
    </behaviorExtensions>
</extensions>    

Anschließend erstellt der Dienst endpointBehavior-Konfigurationen für jede Variante:

<endpointBehaviors>
    <behavior name="endpoint1">
        <filteringEndpointBehavior variation="1" />
    </behavior>
    <behavior name="endpoint2">
        <filteringEndpointBehavior variation="2" />
    </behavior>
</endpointBehaviors>

Schließlich verweist der Endpunkt des Diensts auf eine der behaviorConfigurations:

<endpoint address=""
        bindingConfiguration="ws"
        listenUri="" 
        binding="wsHttpBinding"
        contract="Microsoft.ServiceModel.Samples.IHello" 
        behaviorConfiguration="endpoint2" />

Die Implementierung der Clientanwendung ist einfach. Sie erstellt zwei Kanäle zum URI des Diensts (indem der Wert als der zweite (via)-Parameter an CreateChannel übergeben wird) und sendet eine einzelne Nachricht auf jedem Kanal, verwendet aber jeweils verschiedene Endpunktadressen. Infolgedessen besitzen die vom Client ausgehenden Nachrichten unterschiedliche To-Ziele, und der Server antwortet entsprechend, wie von der Ausgabe des Clients veranschaulicht:

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

Durch einen Wechsel der Variante in der Konfigurationsdatei des Servers wird der Filter getauscht, und der Client sieht das andere Verhalten (die Nachricht an urn:e ist erfolgreich, die Nachricht an urn:a schlägt jedoch fehl).

<endpoint address=""
          bindingConfiguration="ws"
          listenUri="" 
          binding="wsHttpBinding"
          contract="Microsoft.ServiceModel.Samples.IHello" 
          behaviorConfiguration="endpoint1" />

So richten Sie das Beispiel ein, erstellen es und führen es aus

  1. Folgen Sie zum Erstellen der Lösung den unter Erstellen der Windows Communication Foundation-Beispiele aufgeführten Anweisungen.

  2. Wenn Sie das Beispiel in einer Konfiguration mit einem einzigen Computer ausführen möchten, folgen Sie den unter Durchführen der Windows Communication Foundation-Beispiele aufgeführten Anweisungen.

  3. Wenn Sie das Beispiel in einer computerübergreifenden Konfiguration ausführen möchten, befolgen Sie die Anweisungen in Durchführen der Windows Communication Foundation-Beispiele, und ändern Sie die folgende Zeile in "Client.cs".

    Uri serviceVia = new Uri("https://localhost/ServiceModelSamples/service.svc");
    

    Ersetzen Sie "localhost" mit dem Namen des Servers.

    Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");
    

Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.