Client-Kanalebenenprogrammierung
In diesem Thema wird das Schreiben einer Windows Communication Foundation (WCF) Client-Anwendung ohne Verwenden der System.ServiceModel.ClientBase<TChannel>-Klasse und der zugehörigen Objektmodelle beschrieben.
Senden von Nachrichten
Um für das Senden von Nachrichten und das Empfangen und Verarbeiten von Antworten bereit zu sein, sind die folgenden Schritte erforderlich:
Erstellen Sie eine Bindung.
Erstellen einer Kanalfactory.
Erstellen eines Kanals
Senden einer Anforderung und Lesen der Antwort.
Schließen Sie alle Kanalobjekte.
Erstellen einer Bindung
Ähnlich wie beim empfangenden Fall (siehe Programmierung auf Dienstkanalebene), beginnt das Senden von Nachrichten mit dem Erstellen einer Bindung. In diesem Beispiel wird eine neue System.ServiceModel.Channels.CustomBinding erstellt und ein System.ServiceModel.Channels.HttpTransportBindingElement seiner Elementauflistung hinzugefügt.
Erstellen einer ChannelFactory
Anstatt einen System.ServiceModel.Channels.IChannelListener zu erstellen, wird hier eine System.ServiceModel.ChannelFactory<TChannel> erstellt, indem ChannelFactory.CreateFactory auf der Bindung aufgerufen wird, bei der der Typparameter System.ServiceModel.Channels.IRequestChannel ist. Während die Kanallistener von der Seite verwendet werden, die auf eingehende Nachrichten wartet, werden Kanalfactorys von der Seite verwendet, die die Kommunikation für die Erstellung eines Kanals initiiert. Wie Kanallistener müssen auch Kanalfactorys zuerst geöffnet werden, bevor sie verwendet werden können.
Erstellen eines Kanals
Wir rufen dann ChannelFactory<TChannel>.CreateChannel auf, um einen IRequestChannel zu erstellen. Dieser Aufruf nimmt die Adresse des Endpunkts, mit dem wir mithilfe des neu erstellten Kanals kommunizieren möchten. Nachdem wir einen Kanal haben, führen wir einen Öffnen-Vorgang an diesem durch, um ihn in einen Bereitschaftsstatus für die Kommunikation zu versetzen. Abhängig von der Natur des Transports initiiert dieser Aufruf zum Öffnen möglicherweise eine Verbindung mit dem Zielendpunkt, oder es geschieht nichts auf dem Netzwerk.
Senden einer Anforderung und Lesen der Antwort
Nachdem wir einen offenen Kanal erhalten haben, können wir eine Nachricht erstellen und die Anforderungsmethode des Kanals nutzen, um die Anforderung zu senden und dann auf die Zustellung der Antwort zu warten. Wird diese Methode zurückgegeben, verfügen wir über eine Antwortnachricht, die wir lesen können, um die Antwort des Endpunkts herauszufinden.
Schließen von Objekten
Um Ressourcenverluste zu vermeiden, schließen wir in Kommunikationsvorgängen verwendete Objekte, wenn sie nicht mehr benötigt werden.
Das folgende Codebeispiel zeigt einen grundlegenden Client, der die Kanalfactory zum Senden einer Nachricht und zum Lesen der Antwort verwendet.
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
namespace ProgrammingChannels
{
class Client
{
static void RunClient()
{
//Step1: Create a binding with just HTTP.
BindingElement[] bindingElements = new BindingElement[2];
bindingElements[0] = new TextMessageEncodingBindingElement();
bindingElements[1] = new HttpTransportBindingElement();
CustomBinding binding = new CustomBinding(bindingElements);
//Step2: Use the binding to build the channel factory.
IChannelFactory<IRequestChannel> factory =
binding.BuildChannelFactory<IRequestChannel>(
new BindingParameterCollection());
//Open the channel factory.
factory.Open();
//Step3: Use the channel factory to create a channel.
IRequestChannel channel = factory.CreateChannel(
new EndpointAddress("http://localhost:8080/channelapp"));
channel.Open();
//Step4: Create a message.
Message requestmessage = Message.CreateMessage(
binding.MessageVersion,
"http://contoso.com/someaction",
"This is the body data");
//Send message.
Message replymessage = channel.Request(requestmessage);
Console.WriteLine("Reply message received");
Console.WriteLine("Reply action: {0}",
replymessage.Headers.Action);
string data = replymessage.GetBody<string>();
Console.WriteLine("Reply content: {0}", data);
//Step5: Do not forget to close the message.
replymessage.Close();
//Do not forget to close the channel.
channel.Close();
//Do not forget to close the factory.
factory.Close();
}
public static void Main()
{
Console.WriteLine("Press [ENTER] when service is ready");
Console.ReadLine();
RunClient();
Console.WriteLine("Press [ENTER] to exit");
Console.ReadLine();
}
}
}
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Configuration
Namespace ProgrammingChannels
Friend Class Client
Private Shared Sub RunClient()
'Step1: Create a binding with just HTTP.
Dim bindingElements(1) As BindingElement = {New TextMessageEncodingBindingElement(), _
New HttpTransportBindingElement()}
Dim binding As New CustomBinding(bindingElements)
'Step2: Use the binding to build the channel factory.
Dim factory = binding.BuildChannelFactory(Of IRequestChannel)(New BindingParameterCollection())
'Open the channel factory.
factory.Open()
'Step3: Use the channel factory to create a channel.
Dim channel = factory.CreateChannel(New EndpointAddress("http://localhost:8080/channelapp"))
channel.Open()
'Step4: Create a message.
Dim requestmessage = Message.CreateMessage(binding.MessageVersion, _
"http://contoso.com/someaction", _
"This is the body data")
'Send message.
Dim replymessage = channel.Request(requestmessage)
Console.WriteLine("Reply message received")
Console.WriteLine("Reply action: {0}", replymessage.Headers.Action)
Dim data = replymessage.GetBody(Of String)()
Console.WriteLine("Reply content: {0}", data)
'Step5: Do not forget to close the message.
replymessage.Close()
'Do not forget to close the channel.
channel.Close()
'Do not forget to close the factory.
factory.Close()
End Sub
Public Shared Sub Main()
Console.WriteLine("Press [ENTER] when service is ready")
Console.ReadLine()
RunClient()
Console.WriteLine("Press [ENTER] to exit")
Console.ReadLine()
End Sub
End Class
End Namespace