Auswählen eines NachrichtenaustauschmustersChoosing a Message Exchange Pattern

Der erste Schritt beim Schreiben eines benutzerdefinierten Transports besteht, zu entscheiden, welche Nachrichtenaustauschmuster (oder Nachrichtenaustauschmuster) für die von Ihnen entwickelten Kanal erforderlich sind.The first step in writing a custom transport is to decide which message exchange patterns (or MEPs) are required for the channel you are developing. In diesem Thema werden die verfügbaren Optionen beschrieben und die verschiedenen Anforderungen erläutert.This topic describes the options available and discusses the various requirements. Dies ist die erste Aufgabe in der Aufgabenliste kanalentwicklung in beschriebenen Entwickeln von Kanälen.This is the first task in the channel development task list described in Developing Channels.

Sechs NachrichtenaustauschmusterSix Message Exchange Patterns

Es stehen drei Nachrichtenaustauschmuster zur Auswahl:There are three MEPs to choose from:

  • Datagramm (IInputChannel und IOutputChannel)Datagram (IInputChannel and IOutputChannel)

    Bei Verwendung ein Datagramm-Nachrichtenaustauschmusters sendet ein Client eine Nachricht über einen auslösen und vergessen Exchange.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 und IReplyChannel)Request-Response (IRequestChannel and 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 Anforderung-Antwort-Aufrufe sind Remoteprozeduraufrufe (RPC) und Browser-GET-Anforderungen.Examples of request-response calls are remote procedure calls (RPC) and browser GET requests. 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.

Auswählen eines nachrichtenaustauschmustersChoosing a message exchange pattern
Die drei grundlegenden NachrichtenaustauschmusterThe three basic message exchange patterns. von oben nach unten: Datagramm, Anforderung-Antwort und Duplex.Top to bottom: datagram, request-response, and duplex.

Jedes dieser Nachrichtenaustauschmuster kann außerdem unterstützen Sitzungen.Each of these MEPs can also support sessions. Eine Sitzung (und Implementierung von System.ServiceModel.Channels.ISessionChannel<TSession> des Typs System.ServiceModel.Channels.ISession) korreliert alle in einem Kanal gesendeten und empfangenen Nachrichten.A session (and implementation of System.ServiceModel.Channels.ISessionChannel<TSession> of type System.ServiceModel.Channels.ISession) correlates all messages sent and received on a channel. Das Anforderung-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 Anforderung-Antwort-Muster, das Sitzungen unterstützt, dass alle Anforderung/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. Daher stehen insgesamt sechs Nachrichtenaustauschmuster zur Auswahl:This gives you a total of six MEPs to choose from:

  • DatagrammDatagram

  • Anforderung-AntwortRequest-response

  • DuplexDuplex

  • Datagramm mit SitzungenDatagram with sessions

  • Anforderung-Antwort mit SitzungenRequest-response with sessions

  • Duplex mit SitzungenDuplex with sessions

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.

Sitzungen und sitzungsbasierte KanäleSessions and Sessionful Channels

Im Bereich der Netzwerke gibt es verbindungsorientierte Protokolle (z. B. TCP) und verbindungslose Protokolle (z. B. UDP).In the networking world, there are connection-oriented protocols (for example, TCP) and connection-less protocols (for example, UDP). WCF verwendet den Begriff Sitzung, um eine Verbindung-verbindungsähnliche logische Abstraktion.WCF uses the term session to mean a connection-like logical abstraction. Sitzungsbasierte WCF-Protokolle sind mit verbindungsorientierten Netzwerkprotokollen vergleichbar, und nicht sitzungsbasierte Protokolle entsprechen verbindungslosen Netzwerkprotokollen.Sessionful WCF protocols are similar to connection-oriented network protocols and sessionless WCF protocols are similar to connection-less network protocols.

Im Kanalobjektmodell manifestiert sich jede logische Sitzung als Instanz eines sitzungsbasierten Kanals.In the channel object model, each logical session manifests as an instance of a sessionful channel. Daher entspricht jede neue vom Client erstellte und vom Dienst akzeptierte Sitzung einem neuen sitzungsbasierten Kanal auf jeder Seite.Therefore every new session created by the client, and accepted on the service, corresponds to a new sessionful channel on each side. Das folgende Diagramm zeigt oben die Struktur nicht sitzungsbasierter Kanäle und unten die Struktur sitzungsbasierter Kanäle.The following diagram shows, on the top, the structure of sessionless channels, and on the bottom, the structure of sessionful channels.

Auswählen eines nachrichtenaustauschmustersChoosing a message exchange pattern

Ein Client erstellt einen neuen sitzungsbasierten Kanal und sendet eine Nachricht.A client creates a new sessionful channel and sends a message. Auf der Dienstseite empfängt der Kanallistener diese Nachricht und erkennt, dass sie zu einer neuen Sitzung gehört. Daraufhin erstellt er einen neuen sitzungsbasierten Kanal und übergibt diesen an die Anwendung (als Antwort auf den AcceptChannel-Aufruf der Anwendung im Kanallistener).On the service side, the channel listener receives this message and detects that it belongs to a new session so it creates a new sessionful channel and hands it to the application (in response to the application calling AcceptChannel on the channel listener). Die Anwendung empfängt dann diese Nachricht sowie alle nachfolgenden Nachrichten, die in derselben Sitzung über denselben sitzungsbasierten Kanal gesendet werden.The application then receives this message and all subsequent messages sent in the same session through the same sessionful channel.

Ein anderer (oder derselbe) Client erstellt einen neuen sitzungsbasierten Kanal und sendet eine Nachricht.Another client (or the same client) creates a new sessionful and sends a message. Der Kanallistener erkennt, dass diese Nachricht in einer neuen Sitzung enthalten ist, und erstellt einen neuen sitzungsbasierten Kanal. Der Vorgang wird wiederholt.The channel listener detects this message is in a new session and creates a new sessionful channel and the process repeats.

Ohne Sitzungen gibt es keine Korrelation zwischen Kanälen und Sitzungen.Without sessions, there is no correlation between channels and sessions. Daher erstellt ein Kanallistener nur einen Kanal, über den alle empfangenen Nachrichten der Anwendung zugestellt werden.Therefore a channel listener creates only one channel through which all received messages are delivered to the application. Es gibt auch keine Nachrichtenreihenfolge, da es keine Sitzung gibt, in der die Nachrichtenreihenfolge beibehalten werden muss.There is also no message ordering because there is no session within which to maintain message order. Der oberste Teil der vorangehenden Grafik illustriert einen nicht sitzungsbasierten Nachrichtenaustausch.The top portion of the preceding graphic illustrates a sessionless message exchange.

Beginnen und Beenden von SitzungenStarting and Terminating Sessions

Sitzungen werden auf dem Client begonnen, indem einfach ein neuer sitzungsbasierter Kanal erstellt wird.Sessions are started on the client by simply creating a new sessionful channel. Sie werden im Dienst gestartet, wenn der Dienst eine Nachricht empfängt, die in einer neuen Sitzung gesendet wurde.They are started on the service when the service receives a message that was sent in a new session. Ebenso werden Sitzungen durch Schließen oder Abbrechen eines sitzungsbasierten Kanals beendet.Likewise, sessions are terminated by closing or aborting a sessionful channel.

Eine Ausnahme hierzu bildet IDuplexSessionChannel, der sowohl zum Senden als auch zum Empfangen von Nachrichten in einem sitzungsbasierten Duplexkommunikationsmuster verwendet wird.The exception to this is IDuplexSessionChannel which is used for both sending and receiving messages in a duplex, sessionful communication pattern. Es ist möglich, dass eine Seite das Senden von Nachrichten stoppen, jedoch weiterhin Nachrichten empfangen möchte. Daher gibt es beim Verwenden von IDuplexSessionChannel einen Mechanismus, mit dem Sie die Ausgabesitzung schließen können, was darauf hinweist, dass Sie keine weiteren Nachrichten senden, jedoch die Eingabesitzung geöffnet lassen, sodass Sie weiterhin Nachrichten empfangen können.It is possible that one side will want to stop sending messages but continue to receive messages therefore when using IDuplexSessionChannel there is a mechanism that lets you close the output session indicating you will not send any more messages but keep the input session opened allowing you to continue to receive messages.

Im Allgemeinen werden Sitzungen auf der ausgehenden und nicht auf der eingehenden Seite geschlossen,In general, sessions are closed on the outgoing side and not on the incoming side. d. h. sitzungsbasierte Ausgabekanäle können geschlossen werden, und dadurch kann die Sitzung ordnungsgemäß beendet werden.That is, sessionful output channels can be closed, thereby cleanly terminating the session. Durch Schließen eines sitzungsbasierten Ausgabekanals gibt der entsprechende sitzungsbasierte Eingabekanal NULL an die Anwendung zurück mit dem Aufruf IInputChannel.Receive auf dem IDuplexSessionChannel.Closing a sessionful output channel causes the corresponding sessionful input channel to return null to the application calling IInputChannel.Receive on the IDuplexSessionChannel.

Sitzungsbasierte Eingabekanäle sollten jedoch nur geschlossen werden, wenn IInputChannel.Receive auf dem IDuplexSessionChannel NULL zurückgibt, was darauf hinweist, dass die Sitzung bereits geschlossen wurde.However sessionful input channels should not be closed unless IInputChannel.Receive on the IDuplexSessionChannel returns null, indicating that the session is already closed. Wenn IInputChannel.Receive auf dem IDuplexSessionChannel nicht NULL zurückgegeben hat, kann das Schließen eines sitzungsbasierten Eingabekanals eine Ausnahme auslösen, da während des Schließens unerwartete Nachrichten empfangen werden können.If IInputChannel.Receive on the IDuplexSessionChannel has not returned null, closing a sessionful input channel may throw an exception because it may receive unexpected messages while closing. Wenn ein Empfänger eine Sitzung beenden möchte, bevor der Absender dies tut, sollte er Abort im Eingabekanal aufrufen, wodurch die Sitzung sofort beendet wird.If a receiver wishes to terminate a session before the sender does, it should call Abort on the input channel, which abruptly terminates the session.

Schreiben von sitzungsbasierten KanälenWriting Sessionful Channels

Als sitzungsbasierter Kanalautor muss Ihr Kanal einige Voraussetzungen erfüllen, um Sitzungen bereitzustellen.As a sessionful channel author, there are a few things your channel must do to provide sessions. Auf der Senderseite muss Ihr Kanal Folgendes erfüllen:On the send side, your channel needs to:

  • Erstellen Sie für jeden neuen Kanal eine neue Sitzung, und verknüpfen Sie sie mit einer neuen Sitzungs-ID, die einer eindeutigen Zeichenfolge entspricht.For each new channel, create a new session and associate it with a new session id which is a unique string. Oder rufen Sie unterhalb im Stapel eine neue Sitzung aus dem sitzungsbasierten Kanal ab.Or obtain a new session from the sessionful channel below you in the stack.

  • Für jede mit diesem Kanal gesendete Nachricht müssen Sie die Nachricht mit der Sitzung verknüpfen, wenn Ihr Kanal die Sitzung erstellt hat (statt sie von der Ebene unterhalb zu erhalten).For each message sent using this channel, if your channel created the session (as opposed to obtaining it from the layer below you), you need to associate the message with the session. Für Protokollkanäle wird dies i. d. R. durch Hinzufügen eines SOAP-Headers ausgeführt.For protocol channels, this is typically done by adding a SOAP header. Für Transportkanäle wird dies durch Erstellen einer neuen Transportverbindung oder durch Hinzufügen von Sitzungsinformationen zum Framing-Protokoll ausgeführt.For transport channels, this is typically done by creating a new transport connection or adding session information to the framing protocol.

  • Für jede über diesen Kanal gesendete Nachricht müssen Sie die oben erwähnten Zustellungsgarantien zur Verfügung stellen.For each message sent using this channel, you need to provide the delivery guarantees mentioned above. Wenn Sie den Kanal unterhalb zur Bereitstellung der Sitzung verwenden, stellt dieser Kanal auch die Zustellungsgarantien zur Verfügung.If you are relying on the channel below you to provide the session, that channel will also provide the delivery guarantees. Wenn Sie die Sitzung selbst zur Verfügung stellen, müssen Sie diese Garantien als Teil des Protokolls implementieren.If you’re providing the session yourself, you need to implement those guarantees as part of your protocol. Wenn Sie einen Protokollkanal schreiben, der WCF auf beiden Seiten voraussetzt, benötigen Sie im Allgemeinen den TCP-Transportkanal oder den Kanal für zuverlässiges Messaging und sind auf einen der beiden Kanäle zur Bereitstellung einer Sitzung angewiesen.In general, if you are writing a protocol channel that assumes WCF on both sides you may require the TCP transport or the Reliable Messaging channel and rely on either one to provide a session.

  • Wenn ICommunicationObject.Close auf Ihrem Kanal aufgerufen wird, führen Sie die notwendigen Schritte zum Schließen der Sitzung aus, indem Sie entweder den angegebenen Timeout oder den Standardwert verwenden.When ICommunicationObject.Close is called on your channel, perform the necessary work to close the session using either the specified timeout or the default one. Dazu brauchen Sie möglicherweise nur Close auf dem Kanal unterhalb aufzurufen (wenn Sie die Sitzung soeben von diesem erhalten haben), eine spezielle SOAP-Nachricht zu senden oder eine Transportverbindung zu schließen.This can be as simple as calling Close on the channel below you (if you just obtained the session from it) or sending a special SOAP message or closing a transport connection.

  • Wenn Abort auf dem Kanal aufgerufen wird, beenden Sie die Sitzung unvermittelt, ohne E/A auszuführen.When Abort is called on your channel, terminate the session abruptly without performing I/O. Dies bedeutet möglicherweise, nichts zu machen oder eine Netzwerkverbindung oder eine andere Ressource abzubrechen.This may mean doing nothing or may involve aborting a network connection or some other resource.

Auf der Empfängerseite muss Ihr Kanal Folgendes erfüllen:On the receive side, your channel needs to:

  • Für jede eingehende Nachricht muss der Kanallistener die Sitzung erkennen, zu der sie gehört.For each incoming message, the channel listener must detect the session it belongs to. Wenn es sich dabei um die erste Nachricht in der Sitzung handelt, muss der Kanallistener einen neuen Kanal erstellen und ihn vom Aufruf an IChannelListener<TChannel>.AcceptChannel zurückgeben.If this is the first message in the session, the channel listener must create a new channel and return it from the call to IChannelListener<TChannel>.AcceptChannel. Andernfalls muss der Kanallistener den vorhandenen Kanal, der der Sitzung entspricht, suchen und die Nachricht über den Kanal zustellen.Otherwise the channel listener must find the existing channel that corresponds to the session and deliver the message through that channel.

  • Wenn Ihr Kanal die Sitzung (sowie die erforderlichen Zustellungsgarantien) bereitstellt, muss die Empfängerseite möglicherweise einige Aktionen ausführen, wie die Nachrichtenreihenfolge ändern oder Bestätigungen senden.If your channel is providing the session (along with the required delivery guarantees) the receive side may be required to perform some actions such as re-order messages or send acknowledgements.

  • Wenn Close auf Ihrem Kanal aufgerufen wird, führen Sie die notwendigen Schritte zum Schließen der Sitzung aus, indem Sie entweder den angegebenen Timeout oder den Standardwert verwenden.When Close is called on your channel, perform the necessary work to close the session either the specified timeout or the default one. Es könnten Ausnahmen ausgelöst werden, wenn der Kanal eine Nachricht empfängt, während er darauf wartet, dass der Schließen-Timeout abläuft.This could result in exceptions if the channel receives a message while waiting for the close timeout to expire. Der Grund dafür ist, dass sich der Kanal im Schließen-Zustand befindet, wenn er eine Nachricht empfängt. Daher wird eine Ausnahme ausgelöst.That’s because the channel will be in the Closing state when it receives a message so it would throw.

  • Wenn Abort auf dem Kanal aufgerufen wird, beenden Sie die Sitzung unvermittelt, ohne E/A auszuführen.When Abort is called on your channel, terminate the session abruptly without performing I/O. Dies bedeutet möglicherweise, nichts zu machen oder eine Netzwerkverbindung oder eine andere Ressource abzubrechen.Again, this may mean doing nothing or may involve aborting a network connection or some other resource.

Siehe auchSee Also

Übersicht über das KanalmodellChannel Model Overview