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> y su modelo de objetos asociado.
enviar mensajes
Para estar listo para enviar mensajes y recibir y procesar respuestas, se requieren los siguientes pasos:
Cree un enlace.
Cree una fábrica de canales.
Cree un canal.
Envíe una solicitud y lea la respuesta.
Cierre todos los objetos de canal.
Crear un enlace
De forma similar al caso receptor (consulte Service Channel-Level Programming), el envío de mensajes comienza creando un enlace. En este ejemplo se crea un nuevo System.ServiceModel.Channels.CustomBinding y se 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, esta vez creamos un System.ServiceModel.ChannelFactory<TChannel> llamando a ChannelFactory.CreateFactory en la vinculación donde el parámetro de tipo es 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 queremos comunicarnos mediante el nuevo canal que se va a crear. Una vez que tenemos un canal, llamamos a Open para dejarlo listo para la comunicación. Según la naturaleza del transporte, esta llamada a Open puede iniciar una conexión con el punto de conexión de destino o no puede hacer 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 usar el método Request del canal para enviar la solicitud y esperar a que la respuesta vuelva. 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.
Cierre de objetos
Para evitar la pérdida de recursos, se cierran los objetos usados en las comunicaciones cuando ya no son necesarios.
En el siguiente ejemplo de código se muestra un cliente básico utilizando la fábrica 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: {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