Programación a nivel de canal de cliente
En este tema se describe cómo escribir una aplicación cliente de Windows Communication Foundation (WCF) sin usar la clase System.ServiceModel.ClientBase<TChannel> ni su modelo de objetos asociado.
enviar mensajes
Para estar listo para enviar mensajes y recibir y procesar las respuestas, se han de realizar los pasos siguientes:
Cree un enlace.
Crear un generador de canales.
Crear un canal.
Enviar una solicitud y leer la respuesta.
Cerrar todos los objetos de canal.
Crear un enlace
Similar al caso de recepción (consulte Programación de nivel de canal de servicio), el envío de mensajes comienza con la creación de un enlace. Este ejemplo crea un nuevo System.ServiceModel.Channels.CustomBinding y agrega un System.ServiceModel.Channels.HttpTransportBindingElement a su colección Elements.
Creación de un ChannelFactory
En lugar de crear un System.ServiceModel.Channels.IChannelListener, en esta ocasión creamos un System.ServiceModel.ChannelFactory<TChannel> llamando a ChannelFactory.CreateFactory en el enlace donde está el parámetro de tipo System.ServiceModel.Channels.IRequestChannel. Aunque el lado que espera mensajes entrantes usa los agentes de escuchas de canales, el lado que inicia la comunicación para crear un canal emplea los generadores de canales. Al igual que los agentes de escuchas de canales, los generadores de canales se han de abrir primero antes de que puedan utilizarse.
Creación de un canal
A continuación llamamos a ChannelFactory<TChannel>.CreateChannel para crear un IRequestChannel. Esta llamada toma la dirección del punto de conexión con el que deseamos comunicarnos utilizando el nuevo canal que se crea. Una vez que tenemos un canal, llamamos a Open para dejarlo listo para la comunicación. Dependiendo de la naturaleza del transporte, esta llamada a Open puede iniciar una conexión con el punto de conexión de destino o puede que no haga nada en absoluto en la red.
Envío de una solicitud y lectura de la respuesta
Una vez que tenemos un canal abierto, podemos crear un mensaje y utilizar el método Request del canal para enviar la solicitud y esperar a que la respuesta regrese. Cuando este método devuelve, tenemos un mensaje de respuesta que podemos leer para averiguar cuál fue la respuesta del punto de conexión.
Cerrar objetos
Para evitar la pérdida de recursos, cerramos los objetos utilizados en las comunicaciones cuando ya no se necesiten.
El siguiente ejemplo de código muestra un cliente básico que utiliza el generador de canales para enviar un mensaje y leer la respuesta.
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