Freigeben über


Benutzerdefinierter Nachrichteninterceptor

In diesem Beispiel wird die Verwendung des Kanalerweiterbarkeitsmodells veranschaulicht. Es zeigt insbesondere, wie ein benutzerdefiniertes Bindungselement implementiert wird, das Kanalfactorys und Kanallistener erstellt, um sämtliche ein- und ausgehenden Nachrichten an einer bestimmten Stelle im Laufzeitstapel abzufangen. Im Beispiel sind auch ein Client und ein Server, die die Verwendung dieser benutzerdefinierten Factorys veranschaulichen, enthalten.

In diesem Beispiel sind sowohl der Client als auch der Dienst Konsolenprogramme (.exe). Der Client und der Dienst verwenden beide eine allgemeine Bibliothek (.dll), die das benutzerdefinierte Bindungselement und zugewiesene Laufzeitobjekte enthält.

ms751495.note(de-de,VS.100).gifHinweis:
Die Setupprozedur und die Erstellungsanweisungen für dieses Beispiel befinden sich am Ende dieses Abschnitts.

ms751495.Important(de-de,VS.100).gif Hinweis:
Die Beispiele sind möglicherweise bereits auf dem Computer installiert. Überprüfen Sie das folgende (standardmäßige) Verzeichnis, bevor Sie fortfahren.

<Installationslaufwerk>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, rufen Sie Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 auf, um alle Windows Communication Foundation (WCF)- und WF-Beispiele herunterzuladen. Dieses Beispiel befindet sich im folgenden Verzeichnis.

<Installationslaufwerk>:\WF_WCF_Samples\WCF\Extensibility\Channels\MessageInterceptor

Im Beispiel wird die empfohlene Vorgehensweise zum Erstellen eines benutzerdefinierten geschichteten Kanals in Windows Communication Foundation (WCF) anhand des Kanalframeworks und der empfohlenen Vorgehensweisen für WCF beschrieben. Mit folgenden Schritten wird ein benutzerdefinierter geschichteter Kanal erstellt:

  1. Legen Sie fest, welche Kanalform die Kanalfactory und der Kanallistener unterstützen sollen.

  2. Erstellen Sie eine Kanalfactory und einen Kanallistener, die Ihre Kanalformen unterstützen.

  3. Fügen Sie ein Bindungselement hinzu, das den benutzerdefinierten geschichteten Kanal einem Kanalstapel hinzufügt.

  4. Fügen Sie einen Bindungselementerweiterungs-Abschnitt hinzu, um dem Konfigurationssystem das neue Bindungselement verfügbar zu machen.

Kanalformen

Der erste Schritt beim Schreiben eines benutzerdefinierten geschichteten Kanals besteht darin zu entscheiden, welche Formen für den Kanal erforderlich sind. Bei unserem Nachrichteninspektor wird jede Form unterstützt, die die Schicht unterhalb unterstützt (wenn die Schicht unterhalb beispielsweise IOutputChannel und IDuplexSessionChannel erstellen kann, werden ebenfalls IOutputChannel und IDuplexSessionChannel verfügbar gemacht).

Kanalfactory und Listenerfactory

Der nächste Schritt beim Schreiben eines benutzerdefinierten geschichteten Kanals besteht im Erstellen einer Implementierung von IChannelFactory für Clientkanäle und von IChannelListener für Dienstkanäle.

Diese Klassen nehmen eine innere Factory und einen inneren Listener und delegieren alle Aufrufe außer den OnCreateChannel- und OnAcceptChannel-Aufrufen an die innere Factory und den inneren Listener.

    class InterceptingChannelFactory<TChannel> : ChannelFactoryBase<TChannel>
    { ... }
    class InterceptingChannelListener<TChannel> : ListenerFactoryBase<TChannel>
    { ... }

Hinzufügen eines Bindungselements

Das Beispiel definiert ein benutzerdefiniertes Bindungselement: InterceptingBindingElement. InterceptingBindingElement nimmt einen ChannelMessageInterceptor als Eingabe und verwendet diesen ChannelMessageInterceptor zum Bearbeiten von durchkommenden Nachrichten. Dies ist die einzige Klasse, die öffentlich sein muss. Die Factory, der Listener und die Kanäle können alle interne Implementierungen der öffentlichen Laufzeitschnittstellen sein.

public class InterceptingBindingElement : BindingElement

Hinzufügen von Konfigurationsunterstützung

Die Bibliothek definiert einen Konfigurationsabschnittshandler als Bindungselementerweiterungs-Abschnitt, um die Bindungskonfiguration zu integrieren. Die Client- und Serverkonfigurationsdateien müssen die Bindungselementerweiterung auf dem Konfigurationssystem registrieren. Implementierer, die ihr Bindungselement auf dem Konfigurationssystem verfügbar machen möchten, können von dieser Klasse ableiten.

public abstract class InterceptingElement : BindingElementExtensionElement { ... }

Hinzufügen einer Richtlinie

Zum Integrieren mit unserem Richtliniensystem implementiert InterceptingBindingElement IPolicyExportExtension, um die Teilnahme beim Generieren der Richtlinie zu signalisieren. Damit das Importieren einer Richtlinie auf einem generierten Client unterstützt wird, kann der Benutzer eine abgeleitete Klasse von InterceptingBindingElementImporter registrieren und CreateMessageInterceptor() überschreiben, um die richtlinienfähige ChannelMessageInterceptor-Klasse zu generieren.

Beispiel: Zu verwerfender Nachrichteninspektor

Das Beispiel umfasst eine Beispielimplementierung von ChannelMessageInspector, der Meldungen verwirft.

    class DroppingServerElement : InterceptingElement
    {
        protected override ChannelMessageInterceptor CreateMessageInterceptor()
        {
            return new DroppingServerInterceptor();
        }
    }

Sie rufen es wie folgt über die Konfiguration auf:

<configuration>
    ...
    <system.serviceModel>
        ...
        <extensions>
            <bindingElementExtensions>
                <add name="droppingInterceptor" 
                   type=
          "Microsoft.ServiceModel.Samples.DroppingServerElement, library"/>
            </bindingElementExtensions>
        </extensions>
    </system.serviceModel>
</configuration>

Sowohl der Client als auch der Server benutzen den neu erstellten Konfigurationsabschnitt, um die benutzerdefinierten Factorys in die unterste Schicht ihrer Laufzeit-Kanalstapel (über der Transportebene) einzufügen.

<customBinding>
  <binding name="sampleBinding">
    <droppingInterceptor/>
    <httpTransport/>
  </binding>
</customBinding>

Der Client verwendet die MessageInterceptor-Bibliothek, um einen benutzerdefinierten Header für Meldungen mit geraden Zahlen hinzuzufügen. Der Dienst hingegen verwendet die MessageInterceptor-Bibliothek, um alle Meldungen zu verwerfen, die diesen Header nicht enthalten.

Nach Ausführen des Diensts und anschließendem Ausführen des Clients sollte folgende Clientausgabe angezeigt werden:

Reporting the next 10 wind speed
100 kph
Server dropped a message.
90 kph
80 kph
Server dropped a message.
70 kph
60 kph
Server dropped a message.
50 kph
40 kph
Server dropped a message.
30 kph
20 kph
Server dropped a message.
10 kph
Press ENTER to shut down client

Der Client meldet 10 verschiedene Windgeschwindigkeiten an den Dienst, aber nur die Hälfte der Meldungen wird mit dem speziellen Header gekennzeichnet.

Auf dem Dienst sollten Sie die folgende Ausgabe erhalten:

Press ENTER to exit.
Dangerous wind detected! Reported speed (90) is greater than 64 kph.
Dangerous wind detected! Reported speed (70) is greater than 64 kph.
5 wind speed reports have been received.

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

  1. Installieren Sie ASP.NET 4.0 mithilfe des folgenden Befehls.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Vergewissern Sie sich, dass Sie Einmaliges Setupverfahren für Windows Communication Foundation-Beispiele ausgeführt haben.

  3. Folgen Sie den unter Erstellen der Windows Communication Foundation-Beispiele aufgeführten Anweisungen, um die Projektmappe zu erstellen.

  4. Wenn Sie das Beispiel in einer Konfiguration mit einem Computer oder computerübergreifend ausführen möchten, folgen Sie den unter Running the Windows Communication Foundation Samples aufgeführten Anweisungen.

  5. Führen Sie zuerst "Service.exe" und dann "Client.exe" aus, und sehen Sie sich die Ausgabe in beiden Konsolenfenstern an.