WCF之“HelloWorld”(二)

在上一篇文章中创建了一个简单的WCF应用程序,因为太过简单,所以没有作太多的说明。这一篇中,我们一起把他穿的外衣全部给脱了,看看精简版的“HelloWorld”是怎么运行的。

我们知道WCF是通过暴露EndPoint来提供服务的。所以EndPoint就显的尤为重要,先来分析一下EndPoint。

EndPoint由Address,Binding,Contract组成。其中Address指示了服务的位置,Contract暴露了服务提供了什么方法,Binding则负责通讯的细节。本节不准备讨论Address,Contract。我们来看看如何通过Binding来直接通讯。同样,我们新建一个Solution。没有第一个Solution复杂,这个Solution更简单只有两个Console程序组成,但是这个Solution却揭示了通讯的本质。为我们后面进一步探讨通信过程打下了基础。废话不多说,先看看这个Solutin

其中Client为客户端,Server为服务端。代码先粘出来,后面解释。

首先看看Server端的实现:

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Xml;
namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:6789/HelloWorld");
            BasicHttpBinding serverBinding = new BasicHttpBinding();
            IChannelListener<IReplyChannel> listener = serverBinding.BuildChannelListener<IReplyChannel>(uri);
            listener.Open();
            IReplyChannel channel = listener.AcceptChannel();
            channel.Open();
            RequestContext context = channel.ReceiveRequest();
            Message message = context.RequestMessage;
            XmlDictionaryReader reader = message.GetReaderAtBodyContents();
            Console.WriteLine("ClientMessage is : "+reader.ReadElementContentAsString());
            Message replyMessage = Message.CreateMessage(MessageVersion.Soap11, "Test", "This is ReplyMessage");
            context.Reply(replyMessage);
            channel.Close();
            listener.Close();
            Console.Read();


        }
    }
}

一句一句解释下上述代码:

第一步:定义一个binding,这里我们使用BasicHttpBinding

第二步: IChannelListener<IReplyChannel> listener = serverBinding.BuildChannelListener<IReplyChannel>(uri);

创建信道监听器ChannelListener,何为信道监听器,也就是用来在服务端监听客户端的请求,如果作过Socket编程的话,这应该很好理解,在监听过程中他会阻塞线程,直到客户端的请求到达。

第三步:listener.open();打开信道监听器

第四步:IReplyChannel channel = listener.AcceptChannel();
利用listener的AcceptChannel()方法得到channel。这里要多说一句,这里又牵涉到了Channel Sharp,因为我使用的是Request\Reply模式,所以在服务端就是ReplyChannel。这里如果不懂没有关系,这些在后面都会讲到。

第五步:打开信道。channel.Open();

第六步: RequestContext context = channel.ReceiveRequest();

利用IReplyChannel的ReceiveRequest()阻塞线程直到有服务请求到达并得到RequestContext,ResquestContext中包含了客户端请求的消息---context.RequestMessage。

第七步:打印出客户端来的消息,我们只打印出body部分。

第八步:生成返回到客户端的消息。并利用RequestContext的Reply方法返回给客户端。

第九步:最后的清理工作,关闭listener和channel。

再来看看客户端的代码:

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.IO;
using System.Xml;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            EndpointAddress myEndPoint = new EndpointAddress("http://localhost:6789/HelloWorld");
            BasicHttpBinding clientBinding = new BasicHttpBinding();
            IChannelFactory<IRequestChannel> factory = clientBinding.BuildChannelFactory<IRequestChannel>();
            factory.Open();
            IRequestChannel clientChannel = factory.CreateChannel(myEndPoint);
            clientChannel.Open();
            Message message = Message.CreateMessage(MessageVersion.Soap11, "test", "HelloWorld");
            Message replyMessage = clientChannel.Request(message);
            XmlDictionaryReader reader = replyMessage.GetReaderAtBodyContents();
            Console.WriteLine("Server ReplyMessage is "+ reader.ReadElementContentAsString());
            clientChannel.Close();
            factory.Close();
            Console.Read();
        }

    }
}

 

客户端的代码很多和服务端一样,我说说和服务端的不同点。

首先:在Request\Reply模式的客户端,Channel Sharp为IRequestChannel。而服务端为IReplyChannel。

其次:客户端不需要监听,所以客户端是一个ChannelFactory,其他就和服务端差不多了。

 

我们来看看结果:

上面为服务端的运行界面,下面为客户端的运行界面。

这篇文章中出现了很多新的词汇,channelListener,ChannelFactory,Channel Sharp等等。现在只要有这些概念就行了。后面会针对每一种词汇进行单独解释的。

源代码可以在这里下载:/Files/TylerLan/BasicCommunication.rar

posted @ 2008-12-15 14:52  TylerLan  阅读(429)  评论(2编辑  收藏  举报