Transport: UDPTransport: UDP

Beispiel für den UDP-Transport veranschaulicht, wie UDP-Unicast und Multicast als benutzerdefinierte Windows Communication Foundation (WCF)-Transport implementiert wird.The UDP Transport sample demonstrates how to implement UDP unicast and multicast as a custom Windows Communication Foundation (WCF) transport. Im Beispiel wird die empfohlene Vorgehensweise zum Erstellen eines benutzerdefinierten Transports in WCF anhand des kanalframeworks und WCF-best Practices beschrieben.The sample describes the recommended procedure for creating a custom transport in WCF, by using the channel framework and following WCF best practices. Die Schritte zum Erstellen eines benutzerdefinierten Transports lauten wie folgt:The steps to create a custom transport are as follows:

  1. Entscheiden, welche des Kanals Nachrichtenaustauschmuster (IOutputChannel, IInputChannel, IDuplexChannel, IRequestChannel oder IReplyChannel) die ChannelFactory und Kanallistener unterstützen.Decide which of the channel Message Exchange Patterns (IOutputChannel, IInputChannel, IDuplexChannel, IRequestChannel, or IReplyChannel) your ChannelFactory and ChannelListener will support. Dann entscheiden Sie sich, ob Sie die sitzungsbasierten Variationen dieser Schnittstellen unterstützen.Then decide whether you will support the sessionful variations of these interfaces.

  2. Erstellen Sie eine Kanalfactory und einen Kanallistener, die Ihr Nachrichtenaustauschmuster unterstützen.Create a channel factory and listener that support your Message Exchange Pattern.

  3. Stellen Sie sicher, dass alle netzwerkspezifischen Ausnahmen zu der entsprechenden abgeleiteten Klasse von CommunicationException normalisiert werden.Ensure that any network-specific exceptions are normalized to the appropriate derived class of CommunicationException.

  4. Hinzufügen einer <Bindung > Element, das den benutzerdefinierten Transport einem Kanalstapel hinzufügt.Add a <binding> element that adds the custom transport to a channel stack. Weitere Informationen finden Sie unter Hinzufügen eines Bindungselements.For more information, see Adding a Binding Element.

  5. Fügen Sie einen Bindungselementerweiterungs-Abschnitt hinzu, um das neue Bindungselement für das Konfigurationssystem verfügbar zu machen.Add a binding element extension section to expose the new binding element to the configuration system.

  6. Fügen Sie Metadatenerweiterungen hinzu, um anderen Endpunkten Funktionen mitzuteilen.Add metadata extensions to communicate capabilities to other endpoints.

  7. Fügen Sie eine Bindung hinzu, die einen Stapel mit Bindungselementen entsprechend einem genau definierten Profil vorkonfiguriert.Add a binding that pre-configures a stack of binding elements according to a well-defined profile. Weitere Informationen finden Sie unter Hinzufügen einer Standardbindung.For more information, see Adding a Standard Binding.

  8. Fügen Sie einen Bindungsabschnitt und ein Bindungskonfigurationselement hinzu, um die Bindung für das Konfigurationssystem verfügbar zu machen.Add a binding section and binding configuration element to expose the binding to the configuration system. Weitere Informationen finden Sie unter Hinzufügen von Konfigurationsunterstützung.For more information, see Adding Configuration Support.

NachrichtenaustauschmusterMessage Exchange Patterns

Der erste Schritt beim Schreiben eines benutzerdefinierten Transports besteht darin zu entscheiden, welche Nachrichtenaustauschmuster für den Transport erforderlich sind.The first step in writing a custom transport is to decide which Message Exchange Patterns (MEPs) are required for the transport. Es stehen drei Nachrichtenaustauschmuster zur Auswahl:There are three MEPs to choose from:

  • Datagramm (IInputChannel/IOutputChannel)Datagram (IInputChannel/IOutputChannel)

    Bei Verwendung eines Datagramm-Nachrichtenaustauschmusters sendet ein Client eine Nachricht mit einem "fire and forget"-Austausch.When using a datagram MEP, a client sends a message using a "fire and forget" exchange. Ein "fire and forget"-Austausch erfordert eine Out-of-Band-Bestätigung für die erfolgreiche Zustellung.A fire and forget exchange is one that requires out-of-band confirmation of successful delivery. Die Nachricht könnte unterwegs verloren gehen und den Dienst nicht erreichen.The message might be lost in transit and never reach the service. Wenn der Sendevorgang auf der Clientseite erfolgreich abgeschlossen wird, stellt dies keine Garantie dar, dass der Remoteendpunkt die Nachricht erhalten hat.If the send operation completes successfully at the client end, it does not guarantee that the remote endpoint has received the message. Das Datagramm ist ein wesentlicher Baustein für den Nachrichtenaustausch, da Sie eigene Protokolle damit erstellen können, einschließlich zuverlässiger Protokolle und sicherer Protokolle.The datagram is a fundamental building block for messaging, as you can build your own protocols on top of it—including reliable protocols and secure protocols. Clientdatagrammkanäle implementieren die IOutputChannel-Schnittstelle, und Dienstdatagrammkanäle implementieren die IInputChannel-Schnittstelle.Client datagram channels implement the IOutputChannel interface and service datagram channels implement the IInputChannel interface.

  • Anforderung-Antwort (IRequestChannel/IReplyChannel)Request-Response (IRequestChannel/IReplyChannel)

    In diesem Nachrichtenaustauschmuster wird eine Nachricht gesendet, und eine Antwort wird empfangen.In this MEP, a message is sent, and a reply is received. Das Muster besteht aus Anforderungs-Antwort-Paaren.The pattern consists of request-response pairs. Beispiele für Anforderungs-Antwort-Aufrufe sind Remoteprozeduraufrufe (RPC) und Browser-GET-Anforderungen.Examples of request-response calls are remote procedure calls (RPC) and browser GETs. Dieses Muster wird auch als Halbduplex bezeichnet.This pattern is also known as Half-Duplex. In diesem Nachrichtenaustauschmuster implementieren Clientkanäle IRequestChannel, und Dienstkanäle implementieren IReplyChannel.In this MEP, client channels implement IRequestChannel and service channels implement IReplyChannel.

  • Duplex (IDuplexChannel)Duplex (IDuplexChannel)

    Das Duplex-Nachrichtenaustauschmuster ermöglicht, dass eine willkürliche Anzahl von Nachrichten von einem Client gesendet und in beliebiger Reihenfolge empfangen wird.The duplex MEP allows an arbitrary number of messages to be sent by a client and received in any order. Das Duplex-Nachrichtenaustauschmuster ist mit einem Telefongespräch vergleichbar, bei dem jedes gesprochene Wort einer Nachricht entspricht.The duplex MEP is like a phone conversation, where each word being spoken is a message. Da beide Teilnehmer in diesem Nachrichtenaustauschmuster senden und empfangen können, ist die vom Client und von den Dienstkanälen implementierte Schnittstelle IDuplexChannel.Because both sides can send and receive in this MEP, the interface implemented by the client and service channels is IDuplexChannel.

Jedes dieser Nachrichtenaustauschmuster kann außerdem Sitzungen unterstützen.Each of these MEPs can also support sessions. Die neue Funktion von sitzungsfähigen Kanälen besteht darin, dass alle in einem Kanal gesendeten und empfangenen Nachrichten korreliert werden.The added functionality provided by a session-aware channel is that it correlates all messages sent and received on a channel. Das Anforderungs-Antwort-Muster ist eine eigenständige, aus zwei Nachrichten bestehende Sitzung, da die Anforderung und die Antwort korreliert werden.The Request-Response pattern is a stand-alone two-message session, as the request and reply are correlated. Demgegenüber impliziert das Anforderungs-Antwort-Muster, das Sitzungen unterstützt, dass alle Anforderungs-/Antwort-Paare in diesem Kanal miteinander korreliert werden.In contrast, the Request-Response pattern that supports sessions implies that all request/response pairs on that channel are correlated with each other. Dadurch ergeben sich sechs Nachrichtenaustauschmuster zur Auswahl: Datagramm, Anforderung-Antwort, Duplex, Datagramm mit Sitzungen, Anforderung-Antwort mit Sitzungen und Duplex mit Sitzungen.This gives you a total of six MEPs—Datagram, Request-Response, Duplex, Datagram with sessions, Request-Response with sessions, and Duplex with sessions—to choose from.

Hinweis

Für den UDP-Transport wird nur das Nachrichtenaustauschmuster Datagramm unterstützt, da UDP grundsätzlich ein "fire and forget"-Protokoll ist.For the UDP transport, the only MEP that is supported is Datagram, because UDP is inherently a "fire and forget" protocol.

Der ICommunicationObject- und der WCF-ObjektlebenszyklusThe ICommunicationObject and the WCF object lifecycle

WCF bietet einen allgemeinen Zustandsautomaten, der verwendet wird, für die Verwaltung des Lebenszyklus von Objekten wie IChannel, IChannelFactory, und IChannelListener , die für die Kommunikation verwendet werden.WCF has a common state machine that is used for managing the lifecycle of objects like IChannel, IChannelFactory, and IChannelListener that are used for communication. Es gibt fünf Zustände, in denen diese Kommunikationsobjekte vorhanden sein können.There are five states in which these communication objects can exist. Die Zustände werden durch die CommunicationState-Enumeration dargestellt und lauten wie folgt:These states are represented by the CommunicationState enumeration, and are as follows:

  • Created: Dies ist der Zustand eines ICommunicationObject, wenn es zuerst instanziiert wird.Created: This is the state of a ICommunicationObject when it is first instantiated. In diesem Zustand tritt keine Eingabe/Ausgabe (E/A) auf.No input/output (I/O) occurs in this state.

  • Opening: Das Objekt geht zu diesem Zustand über, wenn Open aufgerufen wird.Opening: Objects transition to this state when Open is called. An diesem Punkt werden Eigenschaften unveränderlich gemacht, und Eingabe/Ausgabe kann beginnen.At this point properties are made immutable, and input/output can begin. Dieser Übergang ist nur vom Created-Zustand aus gültig.This transition is valid only from the Created state.

  • Opened: Das Objekt geht zu diesem Zustand über, wenn der geöffnete Prozess abgeschlossen wird.Opened: Objects transition to this state when the open process completes. Dieser Übergang ist nur vom Opening-Zustand aus gültig.This transition is valid only from the Opening state. An diesem Punkt ist das Objekt für die Übertragung voll verwendbar.At this point, the object is fully usable for transfer.

  • Closing: Das Objekt geht zu diesem Zustand über, wenn Close für ein ordnungsgemäßes Herunterfahren aufgerufen wird.Closing: Objects transition to this state when Close is called for a graceful shutdown. Dieser Übergang ist nur vom Opened-Zustand aus gültig.This transition is valid only from the Opened state.

  • Closed: Objekte im Closed-Zustand sind nicht mehr verwendbar.Closed: In the Closed state objects are no longer usable. Im Allgemeinen steht der größte Teil der Konfiguration noch zur Ansicht bereit, es kann aber keine Kommunikation auftreten.In general, most configuration is still accessible for inspection, but no communication can occur. Dieser Zustand ist mit "Verworfen" vergleichbar.This state is equivalent to being disposed.

  • Faulted: Auf Objekte im Faulted-Zustand kann für die Inspektion zugegriffen werden, sie sind aber nicht mehr verwendbar.Faulted: In the Faulted state, objects are accessible to inspection but no longer usable. Wenn ein nicht behebbarer Fehler auftritt, geht das Objekt in diesen Zustand über.When a non-recoverable error occurs, the object transitions into this state. Der einzige gültige Übergang in diesem Zustand wird in der Closed Zustand.The only valid transition from this state is into the Closed state.

Es gibt Ereignisse, die für jeden Zustandsübergang ausgelöst werden.There are events that fire for each state transition. Die Abort-Methode kann jederzeit aufgerufen werden und sorgt dafür, dass das Objekt sofort vom aktuellen Zustand in den Closed-Zustand übergeht.The Abort method can be called at any time, and causes the object to transition immediately from its current state into the Closed state. Beim Aufrufen von Abort wird nicht abgeschlossene Arbeit beendet.Calling Abort terminates any unfinished work.

Kanalfactory und KanallistenerChannel Factory and Channel Listener

Der nächste Schritt beim Schreiben eines benutzerdefinierten Transports besteht im Erstellen einer Implementierung von IChannelFactory für Clientkanäle und von IChannelListener für Dienstkanäle.The next step in writing a custom transport is to create an implementation of IChannelFactory for client channels and of IChannelListener for service channels. Die Kanalebene verwendet ein Factorymuster zum Erstellen von Kanälen.The channel layer uses a factory pattern for constructing channels. WCF stellt basisklassenhilfen für diesen Prozess bereit.WCF provides base class helpers for this process.

In diesem Beispiel ist die Factoryimplementierung in "UdpChannelFactory.cs" enthalten, und die Listenerimplementierung ist in "UdpChannelListener.cs" enthalten.In this sample, the factory implementation is contained in UdpChannelFactory.cs and the listener implementation is contained in UdpChannelListener.cs. Die IChannel-Implementierungen sind in "UdpOutputChannel.cs" und "UdpInputChannel.cs" enthalten.The IChannel implementations are in UdpOutputChannel.cs and UdpInputChannel.cs.

Die UDP-KanalfactoryThe UDP Channel Factory

Die UdpChannelFactory wird von ChannelFactoryBase abgeleitet.The UdpChannelFactory derives from ChannelFactoryBase. Das Beispiel überschreibt GetProperty, um Zugriff auf die Nachrichtenversion des Nachrichtenencoders zu gewähren.The sample overrides GetProperty to provide access to the message version of the message encoder. Das Beispiel überschreibt auch OnClose, um beim Übergang des Zustandsautomaten die Instanz von BufferManager zu beenden.The sample also overrides OnClose so that we can tear down our instance of BufferManager when the state machine transitions.

Der UDP-AusgabekanalThe UDP Output Channel

Der UdpOutputChannel implementiert IOutputChannel.The UdpOutputChannel implements IOutputChannel. Der Konstruktor überprüft die Argumente und erstellt ein Ziel-EndPoint-Objekt, das auf der übergebenen EndpointAddress basiert.The constructor validates the arguments and constructs a destination EndPoint object based on the EndpointAddress that is passed in.

this.socket = new Socket(this.remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);  

Der Kanal kann ordnungsgemäß oder nicht ordnungsgemäß geschlossen werden.The channel can be closed gracefully or ungracefully. Bei ordnungsgemäßer Schließung wird der Socket geschlossen, und die OnClose-Methode der Basisklasse wird aufgerufen.If the channel is closed gracefully the socket is closed and a call is made to the base class OnClose method. Wenn dadurch eine Ausnahme ausgelöst wird, ruft die Infrastruktur Abort auf, um sicherzustellen, dass der Kanal bereinigt wird.If this throws an exception, the infrastructure calls Abort to ensure the channel is cleaned up.

this.socket.Close(0);  

Implementieren Sie anschließend Send() und BeginSend() / EndSend().We then implement Send() and BeginSend()/EndSend(). Dieser Vorgang ist in zwei Hauptabschnitte unterteilt.This breaks down into two main sections. Serialisieren Sie zuerst die Nachricht in ein Bytearray:First we serialize the message into a byte array.

ArraySegment<byte> messageBuffer = EncodeMessage(message);  

Senden Sie anschließend die resultierenden Daten:Then we send the resulting data on the wire.

this.socket.SendTo(messageBuffer.Array, messageBuffer.Offset, messageBuffer.Count, SocketFlags.None, this.remoteEndPoint);  

Der UdpChannelListenerThe UdpChannelListener

Die UdpChannelListener abgeleitet, dass das Beispiel implementiert die ChannelListenerBase Klasse.The UdpChannelListener that the sample implements derives from the ChannelListenerBase class. Er verwendet einen einzelnen UDP-Socket, um Datagramme zu empfangen.It uses a single UDP socket to receive datagrams. Die OnOpen-Methode empfängt Daten mit dem UDP-Socket in einer asynchronen Schleife.The OnOpen method receives data using the UDP socket in an asynchronous loop. Die Daten werden dann mit dem Nachrichtencodierungsframework in Nachrichten konvertiert:The data are then converted into messages using the Message Encoding Framework.

message = MessageEncoderFactory.Encoder.ReadMessage(new ArraySegment<byte>(buffer, 0, count), bufferManager);  

Da derselbe Datagrammkanal Nachrichten darstellt, die aus einer Reihe von Quellen eintreffen, ist der UdpChannelListener ein Singletonlistener.Because the same datagram channel represents messages that arrive from a number of sources, the UdpChannelListener is a singleton listener. Vorhanden ist, wird bei den meisten, ein aktives IChannel diesem Listener zu einem Zeitpunkt zugeordnet.There is, at most, one active IChannel associated with this listener at a time. In diesem Beispiel wird nur dann ein weiterer generiert, wenn ein Kanal, der mit der AcceptChannel-Methode zurückgegeben wird, anschließend freigegeben wird.The sample generates another one only if a channel that is returned by the AcceptChannel method is subsequently disposed. Wenn eine Nachricht empfangen wird, wird sie in diesem Singletonkanal in die Warteschlange eingereiht.When a message is received, it is enqueued into this singleton channel.

UdpInputChannelUdpInputChannel

Die UdpInputChannel -Klasse implementiert IInputChannel.The UdpInputChannel class implements IInputChannel. Sie besteht aus einer Warteschlange mit eingehenden Nachrichten, die vom UdpChannelListener-Socket gefüllt wird.It consists of a queue of incoming messages that is populated by the UdpChannelListener's socket. Diese Nachrichten werden mit der IInputChannel.Receive-Methode aus der Warteschlange entfernt.These messages are dequeued by the IInputChannel.Receive method.

Hinzufügen eines BindungselementsAdding a Binding Element

Nachdem nun die Factorys und Kanäle erstellt sind, müssen sie der ServiceModel-Laufzeit über eine Bindung verfügbar gemacht werden.Now that the factories and channels are built, we must expose them to the ServiceModel runtime through a binding. Eine Bindung ist eine Auflistung von Bindungselementen, die den mit einer Dienstadresse verknüpften Kommunikationsstapel darstellt.A binding is a collection of binding elements that represents the communication stack associated with a service address. Jedes Element im Stapel wird durch dargestellt eine <Bindung > Element.Each element in the stack is represented by a <binding> element.

Im Beispiel ist das Bindungselement UdpTransportBindingElement, das von TransportBindingElement abgeleitet wird.In the sample, the binding element is UdpTransportBindingElement, which derives from TransportBindingElement. Es überschreibt die folgenden Methoden zum Erstellen der der Bindung zugeordneten Factorys.It overrides the following methods to build the factories associated with our binding.

public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)  
{  
    return (IChannelFactory<TChannel>)(object)new UdpChannelFactory(this, context);  
}  

public IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)  
{  
    return (IChannelListener<TChannel>)(object)new UdpChannelListener(this, context);  
}  

Es enthält auch Member zum Klonen des BindingElement und Zurückgeben unseres Schemas (soap.udp).It also contains members for cloning the BindingElement and returning our scheme (soap.udp).

Hinzufügen von Metadatenunterstützung für ein TransportbindungselementAdding Metadata Support for a Transport Binding Element

Um den Transport in ein Metadatensystem zu integrieren, muss dieser sowohl den Import als auch den Export von Richtlinien unterstützen.To integrate our transport into the metadata system, we must support both the import and export of policy. Dadurch können wir unsere Bindung durch Clients generieren die ServiceModel Metadata Utility Tool (Svcutil.exe).This allows us to generate clients of our binding through the ServiceModel Metadata Utility Tool (Svcutil.exe).

Hinzufügen von WSDL-UnterstützungAdding WSDL Support

Das Transportbindungselement in einer Bindung ist für den Export und Import von Adressierungsinformationen in/zu Metadaten verantwortlich.The transport binding element in a binding is responsible for exporting and importing addressing information in metadata. Bei der Nutzung einer SOAP-Bindung sollte das Transportbindungselement ebenfalls einen korrekten Transport-URI in die Metadaten exportieren.When using a SOAP binding, the transport binding element should also export a correct transport URI in metadata.

WSDL-ExportWSDL Export

Um Adressierungsinformationen zu exportieren, implementiert das UdpTransportBindingElement die IWsdlExportExtension-Schnittstelle.To export addressing information the UdpTransportBindingElement implements the IWsdlExportExtension interface. Die ExportEndpoint-Methode fügt dem WSDL-Port die richtigen Adressierungsinformationen hinzu.The ExportEndpoint method adds the correct addressing information to the WSDL port.

if (context.WsdlPort != null)  
{  
    AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);  
}  

Die UdpTransportBindingElement-Implementierung der ExportEndpoint-Methode exportiert ebenfalls einen Transport-URI, wenn der Endpunkt eine SOAP-Bindung verwendet.The UdpTransportBindingElement implementation of the ExportEndpoint method also exports a transport URI when the endpoint uses a SOAP binding.

WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);  
if (soapBinding != null)  
{  
    soapBinding.Transport = UdpPolicyStrings.UdpNamespace;  
}  

WSDL-ImportWSDL Import

Um das WSDL-Importsystem auf die Handhabung des Imports von Adressen zu erweitern, fügen Sie die folgende Konfiguration zur Konfigurationsdatei für "Svcutil.exe" hinzu (wie in der Datei "Svcutil.exe.config" gezeigt):To extend the WSDL import system to handle importing the addresses, we must add the following configuration to the configuration file for Svcutil.exe as shown in the Svcutil.exe.config file.

<configuration>  
  <system.serviceModel>  
    <client>  
      <metadata>  
        <wsdlImporters>  
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />  
        </policyImporters>  
      </metadata>  
    </client>  
  </system.serviceModel>  
</configuration>  

Bei der Ausführung von "Svcutil.exe" gibt es zwei Optionen, um "Svcutil.exe" dazu zu bewegen, die WSDL-Importerweiterungen zu laden:When running Svcutil.exe, there are two options for getting Svcutil.exe to load the WSDL import extensions:

  1. Verweisen Sie Svcutil.exe Konfigurationsdatei mithilfe der/svcutilconfig:<Datei >.Point Svcutil.exe to our configuration file using the /SvcutilConfig:<file>.

  2. Fügen Sie den Konfigurationsabschnitt zu Svcutil.exe.config im gleichen Verzeichnis wie Svcutil.exe hinzu.Add the configuration section to Svcutil.exe.config in the same directory as Svcutil.exe.

Der UdpBindingElementImporter-Typ implementiert die IWsdlImportExtension-Schnittstelle.The UdpBindingElementImporter type implements the IWsdlImportExtension interface. Die ImportEndpoint-Methode importiert die Adresse vom WSDL-Port.The ImportEndpoint method imports the address from the WSDL port.

BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();  
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();  
if (transportBindingElement is UdpTransportBindingElement)  
{  
    ImportAddress(context);  
}  

Hinzufügen von RichtlinienunterstützungAdding Policy Support

Das benutzerdefinierte Bindungselement kann Richtlinienassertionen in die WSDL-Bindung für einen Dienstendpunkt exportieren, um die Funktionen dieses Bindungselements auszudrücken.The custom binding element can export policy assertions in the WSDL binding for a service endpoint to express the capabilities of that binding element.

RichtlinienexportPolicy Export

Die UdpTransportBindingElement Typ implementiert IPolicyExportExtension Unterstützung für das Exportieren der Richtlinie hinzuzufügen.The UdpTransportBindingElement type implements IPolicyExportExtension to add support for exporting policy. Als Ergebnis schließt System.ServiceModel.MetadataExporter UdpTransportBindingElement in die Generierung der Richtlinie für eine Bindung, die dieses enthält, ein.As a result, System.ServiceModel.MetadataExporter includes UdpTransportBindingElement in the generation of policy for any binding that includes it.

Fügen Sie in IPolicyExportExtension.ExportPolicy eine Assertion für UDP und eine weitere Assertion ein, wenn Sie sich im Multicastmodus befinden.In IPolicyExportExtension.ExportPolicy, we add an assertion for UDP and another assertion if we are in multicast mode. Grund hierfür ist, dass der Multicastmodus Einfluss auf die Art und Weise hat, in der der Kommunikationsstapel erstellt wird, weshalb eine Koordinierung zwischen beiden Seiten stattfinden muss.This is because multicast mode affects how the communication stack is constructed, and thus must be coordinated between both sides.

ICollection<XmlElement> bindingAssertions = context.GetBindingAssertions();  
XmlDocument xmlDocument = new XmlDocument();  
bindingAssertions.Add(xmlDocument.CreateElement(  
UdpPolicyStrings.Prefix, UdpPolicyStrings.TransportAssertion, UdpPolicyStrings.UdpNamespace));  
if (Multicast)  
{  
    bindingAssertions.Add(xmlDocument.CreateElement(
        UdpPolicyStrings.Prefix, 
        UdpPolicyStrings.MulticastAssertion, 
        UdpPolicyStrings.UdpNamespace));  
}  

Da benutzerdefinierte Transportbindungselemente für die Handhabung der Adressierung verantwortlich sind, muss die IPolicyExportExtension-Implementierung auf dem UdpTransportBindingElement auch den Export der geeigneten WS-Adressierungsrichtlinienassertionen handhaben, um die Version der verwendeten WS-Adressierung anzugeben.Because custom transport binding elements are responsible for handling addressing, the IPolicyExportExtension implementation on the UdpTransportBindingElement must also handle exporting the appropriate WS-Addressing policy assertions to indicate the version of WS-Addressing being used.

AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);  

RichtlinienimportPolicy Import

Um das Richtlinienimportsystem zu erweitern, fügen Sie die folgende Konfiguration zur Konfigurationsdatei für "Svcutil.exe" hinzu (wie in der Datei "Svcutil.exe.config" gezeigt):To extend the Policy Import system, we must add the following configuration to the configuration file for Svcutil.exe as shown in the Svcutil.exe.config file.

<configuration>  
  <system.serviceModel>  
    <client>  
      <metadata>  
        <policyImporters>  
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />  
        </policyImporters>  
      </metadata>  
    </client>  
  </system.serviceModel>  
</configuration>  

Dann implementieren Sie IPolicyImporterExtension aus der registrierten Klasse (UdpBindingElementImporter).Then we implement IPolicyImporterExtension from our registered class (UdpBindingElementImporter). Prüfen Sie in ImportPolicy() die Assertionen im entsprechenden Namespace, verarbeiten Sie sie für die Generierung des Transports, und prüfen Sie, ob Multicast vorliegt.In ImportPolicy(), we look through the assertions in our namespace, and process the ones for generating the transport and check whether it is multicast. Entfernen Sie darüber hinaus die gehandhabten Assertionen aus der Liste der Bindungsassertionen.We also must remove the assertions we handle from the list of binding assertions. Erneut stehen bei der Ausführung von "Svcutil.exe" zwei Optionen für die Integration zur Verfügung:Again, when running Svcutil.exe, there are two options for integration:

  1. Verweisen Sie Svcutil.exe Konfigurationsdatei mithilfe der/svcutilconfig:<Datei >.Point Svcutil.exe to our configuration file using the /SvcutilConfig:<file>.

  2. Fügen Sie den Konfigurationsabschnitt zu Svcutil.exe.config im gleichen Verzeichnis wie Svcutil.exe hinzu.Add the configuration section to Svcutil.exe.config in the same directory as Svcutil.exe.

Hinzufügen einer StandardbindungAdding a Standard Binding

Das Bindungselement kann auf die beiden folgenden Arten verwendet werden:Our binding element can be used in the following two ways:

  • Über eine benutzerdefinierte Bindung: Benutzerdefinierte Bindungen erlauben Benutzern, basierend auf einer beliebigen Gruppe von Bindungselementen, eigene Bindungen zu definieren.Through a custom binding: A custom binding allows the user to create their own binding based on an arbitrary set of binding elements.

  • Über eine vom System bereitgestellte Bindung, die das Bindungselement enthält.By using a system-provided binding that includes our binding element. WCF bietet mehrere vom System definierte Bindungen, wie z. B. BasicHttpBinding, NetTcpBinding, und WsHttpBinding.WCF provides a number of these system-defined bindings, such as BasicHttpBinding, NetTcpBinding, and WsHttpBinding. Jede dieser Bindungen wird einem genau definierten Profil zugeordnet.Each of these bindings is associated with a well-defined profile.

Das Beispiel implementiert eine Profilbindung in SampleProfileUdpBinding, die von Binding abgeleitet wurde.The sample implements profile binding in SampleProfileUdpBinding, which derives from Binding. SampleProfileUdpBinding enthält bis zu vier Bindungselemente: UdpTransportBindingElement, TextMessageEncodingBindingElement CompositeDuplexBindingElement und ReliableSessionBindingElement.The SampleProfileUdpBinding contains up to four binding elements within it: UdpTransportBindingElement, TextMessageEncodingBindingElement CompositeDuplexBindingElement, and ReliableSessionBindingElement.

public override BindingElementCollection CreateBindingElements()  
{     
    BindingElementCollection bindingElements = new BindingElementCollection();  
    if (ReliableSessionEnabled)  
    {  
        bindingElements.Add(session);  
        bindingElements.Add(compositeDuplex);  
    }  
    bindingElements.Add(encoding);  
    bindingElements.Add(transport);  
    return bindingElements.Clone();  
}  

Hinzufügen eines benutzerdefinierten StandardbindungsimportprogrammsAdding a Custom Standard Binding Importer

"Svcutil.exe" und der WsdlImporter-Typ erkennen und importieren vom System definierte Bindungen standardmäßig.Svcutil.exe and the WsdlImporter type, by default, recognizes and imports system-defined bindings. Andernfalls wird die Bindung als CustomBinding-Instanz importiert.Otherwise, the binding gets imported as a CustomBinding instance. Zur Aktivierung des Imports der WsdlImporter für Svcutil.exe und den SampleProfileUdpBinding, fungiert der UdpBindingElementImporter auch als benutzerdefiniertes Standardbindungsimportprogramm.To enable Svcutil.exe and the WsdlImporter to import the SampleProfileUdpBinding the UdpBindingElementImporter also acts as a custom standard binding importer.

Ein benutzerdefiniertes Standardbindungsimportprogramm implementiert die ImportEndpoint-Methode auf der IWsdlImportExtension-Schnittstelle, um zu prüfen, ob die aus den Metadaten importierte CustomBinding-Instanz von einer spezifischen Standardbindung hätte generiert werden können.A custom standard binding importer implements the ImportEndpoint method on the IWsdlImportExtension interface to examine the CustomBinding instance imported from metadata to see whether it could have been generated by a specific standard binding.

if (context.Endpoint.Binding is CustomBinding)  
{  
    Binding binding;  
    if (transportBindingElement is UdpTransportBindingElement)  
    {  
        //if TryCreate is true, the CustomBinding will be replace by a SampleProfileUdpBinding in the  
        //generated config file for better typed generation.  
        if (SampleProfileUdpBinding.TryCreate(bindingElements, out binding))  
        {  
            binding.Name = context.Endpoint.Binding.Name;  
            binding.Namespace = context.Endpoint.Binding.Namespace;  
            context.Endpoint.Binding = binding;  
        }  
    }  
}  

Allgemein beinhaltet die Implementierung eines benutzerdefinierten Importprogramms für Standardbindungen die Überprüfung der Eigenschaften der importierten Bindungen, um zu bestätigen, dass sich nur Eigenschaften geändert haben, die von der Standardbindung hätten festgelegt werden können, und es sich bei allen anderen Eigenschaften um die Standardwerte handelt.Generally, implementing a custom standard binding importer involves checking the properties of the imported binding elements to verify that only properties that could have been set by the standard binding have changed and all other properties are their defaults. Eine grundlegende Strategie für die Implementierung eines Standardbindungsimportprogramms ist die Erstellung einer Standardbindung, die Weitergabe der Eigenschaften von den Bindungselementen an die von der Standardbindung unterstützte Standardbindungsinstanz und der Vergleich der Bindungselemente der Standardbindung mit den importierten Bindungselementen.A basic strategy for implementing a standard binding importer is to create an instance of the standard binding, propagate the properties from the binding elements to the standard binding instance that the standard binding supports, and the compare the binding elements from the standard binding with the imported binding elements.

Hinzufügen von KonfigurationsunterstützungAdding Configuration Support

Um unseren Transport durch Konfiguration verfügbar zu machen, müssen Sie zwei Konfigurationsabschnitte implementieren.To expose our transport through configuration, we must implement two configuration sections. Der erste ist ein BindingElementExtensionElement für UdpTransportBindingElement.The first is a BindingElementExtensionElement for UdpTransportBindingElement. Auf diese Weise können CustomBinding-Implementierungen auf das im Beispiel erstellte Bindungselement verweisen.This is so that CustomBinding implementations can reference our binding element. Der zweite ist eine Configuration für SampleProfileUdpBinding.The second is a Configuration for our SampleProfileUdpBinding.

Element für BindungselementerweiterungenBinding Element Extension Element

Der Abschnitt UdpTransportElement ist ein BindingElementExtensionElement, das die UdpTransportBindingElement für das Konfigurationssystem verfügbar macht.The section UdpTransportElement is a BindingElementExtensionElement that exposes UdpTransportBindingElement to the configuration system. Mit wenigen grundlegenden Überschreibungen definiert das Beispiel den Konfigurationsabschnittsnamen, den Typ des Bindungselements und wie das Bindungselement erstellt wird.With a few basic overrides, we define our configuration section name, the type of our binding element and how to create our binding element. Benutzer können dann wie im folgenden Code den Erweiterungsabschnitt in einer Konfigurationsdatei registrieren.We can then register our extension section in a configuration file as shown in the following code.

<configuration>  
  <system.serviceModel>  
    <extensions>  
      <bindingElementExtensions>  
        <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport />  
      </bindingElementExtensions>  
    </extensions>  
  </system.serviceModel>  
</configuration>  

Auf die Erweiterung kann von benutzerdefinierten Bindungen verwiesen werden, um UDP als Transport zu nutzen.The extension can be referenced from custom bindings to use UDP as the transport.

<configuration>  
  <system.serviceModel>  
    <bindings>  
      <customBinding>  
       <binding configurationName="UdpCustomBinding">  
         <udpTransport/>  
       </binding>  
      </customBinding>  
    </bindings>  
  </system.serviceModel>  
</configuration>  

BindungsabschnittBinding Section

Der Abschnitt SampleProfileUdpBindingCollectionElement ist ein StandardBindingCollectionElement, das die SampleProfileUdpBinding für das Konfigurationssystem verfügbar macht.The section SampleProfileUdpBindingCollectionElement is a StandardBindingCollectionElement that exposes SampleProfileUdpBinding to the configuration system. Dem SampleProfileUdpBindingConfigurationElement, das sich von StandardBindingElement herleitet, wird der Großteil der Implementierung übertragen.The bulk of the implementation is delegated to the SampleProfileUdpBindingConfigurationElement, which derives from StandardBindingElement. Die SampleProfileUdpBindingConfigurationElement verfügt über Eigenschaften, die auf die Eigenschaften entsprechen SampleProfileUdpBinding, und die Funktionen für die Zuordnung der ConfigurationElement Bindung.The SampleProfileUdpBindingConfigurationElement has properties that correspond to the properties on SampleProfileUdpBinding, and functions to map from the ConfigurationElement binding. Schließlich wird die OnApplyConfiguration-Methode in der SampleProfileUdpBinding überschrieben. Dies wird im folgenden Beispielcode veranschaulicht.Finally, override the OnApplyConfiguration method in our SampleProfileUdpBinding, as shown in the following sample code.

protected override void OnApplyConfiguration(string configurationName)  
{  
    if (binding == null)
        throw new ArgumentNullException("binding");

    if (binding.GetType() != typeof(SampleProfileUdpBinding))
    {
        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
            "Invalid type for binding. Expected type: {0}. Type passed in: {1}.",
            typeof(SampleProfileUdpBinding).AssemblyQualifiedName,
            binding.GetType().AssemblyQualifiedName));
    }
    SampleProfileUdpBinding udpBinding = (SampleProfileUdpBinding)binding;

    udpBinding.OrderedSession = this.OrderedSession;
    udpBinding.ReliableSessionEnabled = this.ReliableSessionEnabled;
    udpBinding.SessionInactivityTimeout = this.SessionInactivityTimeout;
    if (this.ClientBaseAddress != null)
        udpBinding.ClientBaseAddress = ClientBaseAddress;
}

Um diesen Handler mit dem Konfigurationssystem zu registrieren, fügen Sie der relevanten Konfigurationsdatei den folgenden Abschnitt hinzu.To register this handler with the configuration system, we add the following section to the relevant configuration file.

<configuration>  
  <configSections>  
     <sectionGroup name="system.serviceModel">  
        <sectionGroup name="bindings">  
          <section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport />  
        </sectionGroup>  
     </sectionGroup>  
  </configSections>  
</configuration>  

Darauf kann dann vom serviceModel-Konfigurationsabschnitt verwiesen werden.It can then be referenced from the serviceModel configuration section.

<configuration>  
  <system.serviceModel>  
    <client>  
      <endpoint configurationName="calculator"  
                address="soap.udp://localhost:8001/"   
                bindingConfiguration="CalculatorServer"  
                binding="sampleProfileUdpBinding"   
                contract= "Microsoft.ServiceModel.Samples.ICalculatorContract">  
      </endpoint>  
    </client>  
  </system.serviceModel>  
</configuration>  

Der UDP-Testdienst und der ClientThe UDP Test Service and Client

Testcode für die Verwendung dieses Beispieltransports ist in den UdpTestService- und UdpTestClient-Verzeichnissen verfügbar.Test code for using this sample transport is available in the UdpTestService and UdpTestClient directories. Der Dienstcode besteht aus zwei Tests: Ein Test richtet die Bindungen und Endpunkte über den Code ein und der andere über die Konfiguration.The service code consists of two tests—one test sets up bindings and endpoints from code and the other does it through configuration. Beide Tests verwenden zwei Endpunkte.Both tests use two endpoints. Ein Endpunkt verwendet die SampleUdpProfileBinding mit <ReliableSession > festgelegt true.One endpoint uses the SampleUdpProfileBinding with <reliableSession> set to true. Der andere Endpunkt verwendet eine benutzerdefinierte Bindung mit UdpTransportBindingElement.The other endpoint uses a custom binding with UdpTransportBindingElement. Dies entspricht der Verwendung SampleUdpProfileBinding mit <ReliableSession > festgelegt false.This is equivalent to using SampleUdpProfileBinding with <reliableSession> set to false. Beide Tests erstellen einen Dienst, fügen einen Endpunkt für jede Bindung hinzu, öffnen den Dienst und warten anschließend darauf, dass der Benutzer die EINGABETASTE drückt, bevor der Dienst beendet wird.Both tests create a service, add an endpoint for each binding, open the service and then wait for the user to hit ENTER before closing the service.

Wenn Sie die Testanwendung für den Dienst starten, sollte folgende Ausgabe angezeigt werden:When you start the service test application you should see the following output.

Testing Udp From Code.  
Service is started from code...  
Press <ENTER> to terminate the service and start service from config...  

Sie können dann die Testclientanwendung für die veröffentlichten Endpunkte ausführen.You can then run the test client application against the published endpoints. Die Clienttestanwendung erstellt für jeden Endpunkt einen Client und sendet fünf Nachrichten an jeden Endpunkt.The client test application creates a client for each endpoint and sends five messages to each endpoint. Im Folgenden finden Sie die Ausgabe auf dem Client:The following output is on the client.

Testing Udp From Imported Files Generated By SvcUtil.  
0  
3  
6  
9  
12  
Press <ENTER> to complete test.  

Im Folgenden finden Sie die vollständige Ausgabe auf dem Dienst:The following is the full output on the service.

Service is started from code...  
Press <ENTER> to terminate the service and start service from config...  
Hello, world!  
Hello, world!  
Hello, world!  
Hello, world!  
Hello, world!  
   adding 0 + 0  
   adding 1 + 2  
   adding 2 + 4  
   adding 3 + 6  
   adding 4 + 8  

Um die Clientanwendung für Endpunkte auszuführen, die mithilfe einer Konfiguration veröffentlicht wurden, drücken Sie die EINGABETASTE im Dienst, und führen Sie den Testclient erneut aus.To run the client application against endpoints published using configuration, hit ENTER on the service and then run the test client again. Auf dem Dienst sollten Sie die folgende Ausgabe erhalten:You should see the following output on the service.

Testing Udp From Config.  
Service is started from config...  
Press <ENTER> to terminate the service and exit...  

Durch das erneute Ausführen des Clients werden die gleichen Ergebnisse erzielt wie zuvor.Running the client again yields the same as the preceding results.

Um den Clientcode und die Konfiguration mithilfe von "Svcutil.exe" neu zu generieren, starten Sie die Dienstanwendung, und führen Sie dann "Svcutil.exe" wie folgt aus dem Stammverzeichnis des Beispiels aus:To regenerate the client code and configuration using Svcutil.exe, start the service application and then run the following Svcutil.exe from the root directory of the sample.

svcutil http://localhost:8000/udpsample/ /reference:UdpTranport\bin\UdpTransport.dll /svcutilConfig:svcutil.exe.config  

Beachten Sie, dass "Svcutil.exe" nicht die Bindungserweiterungskonfiguration für SampleProfileUdpBinding generiert. Sie müssen diese daher manuell hinzufügen.Note that Svcutil.exe does not generate the binding extension configuration for the SampleProfileUdpBinding, so you must add it manually.

<configuration>  
  <system.serviceModel>      
    <extensions>  
      <!-- This was added manually because svcutil.exe does not add this extension to the file -->  
      <bindingExtensions>  
        <add name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />  
      </bindingExtensions>  
    </extensions>  
  </system.serviceModel>  
</configuration>  

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample

  1. Führen Sie zum Erstellen der Projektmappe die Anweisungen im Erstellen der Windows Communication Foundation-Beispiele.To build the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  2. Um das Beispiel in einer einzelnen oder computerübergreifenden Konfiguration ausführen möchten, folgen Sie den Anweisungen Ausführen der Windows Communication Foundation-Beispiele.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

  3. Informationen finden Sie im vorhergehenden Abschnitt "Der UDP-Testdienst und der Client".Refer to the preceding "The UDP Test Service and Client" section.

Wichtig

Die Beispiele sind möglicherweise bereits auf dem Computer installiert.The samples may already be installed on your machine. Suchen Sie nach dem folgenden Verzeichnis (Standardverzeichnis), bevor Sie fortfahren.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, fahren Sie mit Windows Communication Foundation (WCF) und Windows Workflow Foundation (WF) Samples for .NET Framework 4 aller Windows Communication Foundation (WCF) herunterladen und WFWF Beispiele.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Dieses Beispiel befindet sich im folgenden Verzeichnis.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\Transport\Udp