Programmazione a livello di canale client
In questo argomento viene descritta la procedura di scrittura di un'applicazione client Windows Communication Foundation (WCF) senza utilizzare la classe System.ServiceModel.ClientBase<TChannel> e il relativo modello a oggetti associato.
Invio di messaggi
Per l'invio di messaggi e la ricezione e l'elaborazione di risposte è necessario eseguire i passaggi seguenti:
Creare un'associazione.
Generare una channel factory.
Creare un canale.
Inviare una richiesta e leggere la riposta.
Chiudere tutti gli oggetti canale.
Creazione di un'associazione
Analogamente al caso di ricezione (vedere Programmazione del servizio a livello di canale), l'invio di messaggi inizia creando un binding. In questo esempio viene creato un nuovo System.ServiceModel.Channels.CustomBinding e viene aggiunto un System.ServiceModel.Channels.HttpTransportBindingElement alla rispettiva raccolta di elementi.
Generare una channel factory.
Anziché creare un System.ServiceModel.Channels.IChannelListener, questa volta è necessario creare una System.ServiceModel.ChannelFactory<TChannel> chiamando ChannelFactory.CreateFactory nell'associazione dove il parametro del tipo è System.ServiceModel.Channels.IRequestChannel. Mentre i listener del canale vengono utilizzati dalla parte in attesa di messaggi in arrivo, le channel factory vengono utilizzate dalla parte che inizia la comunicazione per creare un canale. Esattamente come i listener del canale, le channel factory devono essere aperte prima di poter essere utilizzate.
Creazione di un canale
È necessario quindi chiamare ChannelFactory<TChannel>.CreateChannel per creare un IRequestChannel. Questa chiamata prende l'indirizzo dell'endpoint con il quale si vuole comunicare utilizzando il nuovo canale creato. Quando viene ottenuto un canale, è necessario chiamare Open su di esso per renderlo pronto per la comunicazione. A seconda della natura del trasporto, con questa chiamata a Open viene avviata una connessione con l'endpoint di destinazione oppure non viene eseguita alcuna operazione nella rete.
Invio di una richiesta e lettura della risposta
Dopo che un canale è stato aperto, è possibile creare un messaggio e utilizzare il metodo di richiesta del canale per inviare la richiesta e attendere la risposta. Questo metodo restituisce un messaggio di risposta che è possibile leggere per scoprire quale è stata la risposta dell'endpoint.
Chiusura di oggetti
Per evitare la perdita di risorse, è necessario chiudere gli oggetti utilizzati nelle comunicazioni quando non sono più necessari.
Nell'esempio di codice seguente viene illustrato un client di base che utilizza la channel factory per inviare un messaggio e leggere la risposta.
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