Client-Kanalebenenprogrammierung
In diesem Thema wird beschrieben, wie Sie eine Windows Communication Foundation (WCF)-Clientanwendung schreiben, ohne die System.ServiceModel.ClientBase<TChannel> Klasse und das zugehörige Objektmodell zu verwenden.
Senden von Nachrichten
Um zum Senden von Nachrichten und Empfangen und Verarbeiten von Antworten bereit zu sein, sind die folgenden Schritte erforderlich:
Erstellen Sie eine Bindung.
Bauen Sie eine Kanalfabrik.
Erstellen Sie einen Kanal.
Senden Sie eine Anfrage, und lesen Sie die Antwort.
Schließen Sie alle Kanalobjekte.
Erstellen einer Bindung
Ähnlich wie beim empfangenden Fall (siehe Service Channel-Level Programming), 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 eine System.ServiceModel.Channels.IChannelListenerzu erstellen, erstellen wir diesmal eine System.ServiceModel.ChannelFactory<TChannel>, indem wir ChannelFactory.CreateFactory für die Bindung aufrufen, in der der Typparameter System.ServiceModel.Channels.IRequestChannelist. Während Kanallistener von der Seite verwendet werden, die auf eingehende Nachrichten wartet, werden Kanalfabriken von der Seite verwendet, die die Kommunikation initiiert, um einen Kanal zu erstellen. 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 verwendet die Adresse des Endpunkts, mit dem wir über den neuen, zu erstellenden Kanal kommunizieren möchten. Sobald wir einen Kanal haben, rufen wir 'Open' auf, um ihn in einen Zustand zu versetzen, der für die Kommunikation bereit ist. Je nach Art des Transports kann dieser Aufruf von Open eine Verbindung mit dem Zielendpunkt herstellen oder im Netzwerk gar nichts bewirken.
Senden einer Anforderung und Lesen der Antwort
Sobald wir über einen geöffneten Kanal verfügen, können wir eine Nachricht erstellen und die Anforderungsmethode des Kanals verwenden, um die Anforderung zu senden und zu warten, bis die Antwort zurückkommt. Wenn diese Methode zurückgegeben wird, haben wir eine Antwortnachricht, die wir lesen können, um herauszufinden, was die Antwort des Endpunkts war.
Schließen von Objekten
Um Ressourcenlecks zu vermeiden, schließen wir Objekte, die in der Kommunikation verwendet werden, wenn sie nicht mehr benötigt werden.
Das folgende Codebeispiel zeigt einen einfachen Client, der die Kanalfactory verwendet, um eine Nachricht zu senden und die Antwort zu lesen.
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: {replymessage.Headers.Action}");
string data = replymessage.GetBody<string>();
Console.WriteLine($"Reply content: {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