Benutzerdefinierter Nachrichtenfilter
Das Nachrichtenfilter-Beispiel veranschaulicht, wie die Nachrichtenfilter ersetzt werden, die Windows Communication Foundation (WCF) zum Verteilen von Nachrichten an Endpunkte verwendet.
Hinweis
Die Setupprozedur und die Buildanweisungen 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 MessageFilter angefügten EndpointDispatcher-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(EndpointAddress) ü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
jedoch nicht).
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint1" />
So können Sie das Beispiel einrichten, erstellen und ausführen
Befolgen Sie zum Erstellen der Projektmappe die Anweisungen unter Erstellen der Windows Communication Foundation-Beispiele.
Wenn Sie das Beispiel in einer einzelnen Computerkonfiguration ausführen möchten, folgen Sie den Anweisungen unter Durchführen der Windows Communication Foundation-Beispiele.
Um das Beispiel in einer computerübergreifenden Konfiguration auszuführen, folgen Sie den Anweisungen unter Durchführen der Windows Communication Foundation-Beispiele, und ändern Sie die folgende Zeile in „Client.cs“.
Uri serviceVia = new Uri("http://localhost/ServiceModelSamples/service.svc");
Ersetzen Sie "localhost" mit dem Namen des Servers.
Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");