Client Channel-Level Programming

This topic describes how to write a Windows Communication Foundation (WCF) client application without using the System.ServiceModel.ClientBase<TChannel> class and its associated object model.

Sending Messages

To be ready to send messages and receive and process replies, the following steps are required:

  1. Create a binding.

  2. Build a channel factory.

  3. Create a channel.

  4. Send a request and read the reply.

  5. Close all channel objects.

Creating a Binding

Similar to the receiving case (see Service Channel-Level Programming), sending messages starts by creating a binding. This example creates a new System.ServiceModel.Channels.CustomBinding and adds an System.ServiceModel.Channels.HttpTransportBindingElement to its Elements collection.

Building a ChannelFactory

Instead of creating a System.ServiceModel.Channels.IChannelListener, this time we create a System.ServiceModel.ChannelFactory<TChannel> by calling ChannelFactory.CreateFactory on the binding where the type parameter is System.ServiceModel.Channels.IRequestChannel. While channel listeners are used by the side that waits for incoming messages, channel factories are used by the side that initiates the communication to create a channel. Just like channel listeners, channel factories must be opened first before they can be used.

Creating a Channel

We then call ChannelFactory<TChannel>.CreateChannel to create an IRequestChannel. This call takes the address of the endpoint with which we want to communicate using the new channel being created. Once we have a channel, we call Open on it to put it in a state ready for communication. Depending on the nature of the transport, this call to Open may initiate a connection with the target endpoint or may do nothing at all on the network.

Sending a Request and Reading the Reply

Once we have an opened channel, we can create a message and use the channel’s Request method to send the request and wait for the reply to come back. When this method returns, we have a reply message that we can read to find out what the endpoint’s reply was.

Closing Objects

To avoid leaking resources, we close objects used in communications when they are no longer required.

The following code example shows a basic client using the channel factory to send a message and read the reply.

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