客户端通道级编程

本主题介绍如何在不使用 System.ServiceModel.ClientBase<TChannel> 类及其关联对象模型的情况下编写 Windows Communication Foundation (WCF) 客户端应用程序。

发送消息

若要准备发送消息并接收和处理回复,需要执行下列步骤:

  1. 创建绑定。

  2. 生成通道工厂。

  3. 创建频道。

  4. 发送请求并读取回复。

  5. 关闭所有通道对象。

创建绑定

类似于接收案例(参阅服务通道级编程),通过创建绑定开始发送消息。 本示例创建一个新的 System.ServiceModel.Channels.CustomBinding 并将一个 System.ServiceModel.Channels.HttpTransportBindingElement 添加到其 Elements 集合中。

生成 ChannelFactory

这次我们不创建 System.ServiceModel.Channels.IChannelListener,而是通过调用类型参数为 System.ServiceModel.ChannelFactory<TChannel> 的绑定上的 ChannelFactory.CreateFactory 来创建一个 System.ServiceModel.Channels.IRequestChannel。 当等待传入消息的一方使用通道侦听器时,发起通信以创建通道的一方将使用通道工厂。 和通道侦听器相似,必须先打开通道工厂之后才能使用通道工厂。

创建通道

然后我们调用 ChannelFactory<TChannel>.CreateChannel 来创建一个 IRequestChannel。 此调用接受我们要使用创建的新通道与之通信的终结点的地址。 得到通道后,我们调用它的 Open 以使其处于通信就绪状态。 根据传输的性质,这次对 Open 的调用可能发起与目标终结点的连接,或者在网络上根本不执行任何操作。

发送请求并读取回复

打开通道之后,可以创建消息并使用通道的 Request 方法发送请求并等待回复返回。 当此方法返回时,我们将得到回复消息,可以读取该消息以发现终结点回复的内容。

关闭对象

为避免泄漏资源,我们将关闭通信中不再需要使用的对象。

下面的代码示例演示了一个基本客户端使用通道工厂发送消息并读取回复。

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