WCF从理论到实践(6):WCF架构

前面的几篇文章,分别介绍了WCF的基本知识和Endpoint的三个重要组成部分:Address,Contract,Binding。但无非管中窥豹而已,本文就阐述一下WCF的架构,从整体的角度来重新对WCF加深认识。

 

本文的出发点:

通过阅读本文,能使您获得以下知识:

  1. WCF的架构图
  2. WCF架构的关键元素及其概念
  3. 创建一示例程序,并对其按架构图进行解析

     

本文适合的读者:

本文适合WCF初学者,以前可以对WCF一无所知,本文只作介绍,不涉及WCF技术具体技术难点和介绍。

 

WCF的架构图

下图为WCF的架构图:

 

WCF架构的关键元素及其概念

Contracts and Description (协定和说明):

协定定义消息系统的各个方面。包括Data Contract(数据协定),Message Contract(消息协定) ,Service Contract(服务协定)。Data Contract是WCF中 Service与Client端之间用来交换的数据的格式定义,它采用Xml 架构定义语言(XSD)来定义,使得服务端和客户端都能理解数据格式定义。消息协定能定义消息的特定部分,默认情况下 ,WCF的消息是由固定格式的,但某些情况下,也可以使用Message Contrace来自定义消息格式。服务协定指定服务端公开的方法签名,这些方法能够在远程被调用。举个国家和间谍的例子,A 是国家C派往其它国家的一名间谍,他负责收集情报,被通过某种特定的渠道,将获得的情报发送给国家C,假如A在出去执行任务之前,国家C的特工部门为其编订了一套密文,这个密文只有国家C和特工部门和A知道具体含义,这些密文正是在A与其国家之间进行传递的数据,国家C对密文的制定,正是WCF中对交换数据格式的定义,属于Data Contract范畴,而A在获得情报之后,通过电报的方式将情报发回给国家情报机关,它首先设置电报的发送地址并注明来源,并且将情报信息编码成密文进行发送,对电报报文的格式定义就属于Message Contract范畴,而国家情报机关为A要想接受和对A发送任务命令,必须也提供固定的通讯设施和人,这些能够被A所联络上的通讯设施和人就属于Service Contract的范畴。

Service Runtime(服务运行时)

上面说的协定是在开发wcf服务时候制定的,而服务运行时,是在服务实际运行时候地一些行为控制。ErrorBehavior是在服务出现错误的时候发生的操作,ThrottingBehavior能够限制创建多少个实例和会话,通过这个您能够控制WCF服务的性能,MetaBehavior(元数据行为)控制是否和如何向外部提供元数据。TransactionBehavior能定义事务性,使得当发生异常的时候能进行回滚。DispatchBehavior(调度行为)能控制WCF处理消息的方式,通过扩展性功能可以自定义运行时进程。 例如,消息检查功能用于检查消息的各个部分,使用参数筛选功能可以根据作用于消息头的筛选器来执行预设操作。下图显示了WCF的消息处理流程

 

Messaging(消息传递)

在WCF中,消息是在通道(Channel)中进行传递的。通道是以某种方式对消息进行处理的组件 。一组通道可以组合成"通道堆栈",主要有两大种通道:协议通道和传输通道。协议通道说明数据的格式和交换模式,WS-Security 是对在消息层启用安全性的 WS-Security 规范的实现。 通过 WS-Reliable Messaging 通道可以保证消息的传递。 编码器提供了大量的编码,可使用这些编码来满足消息的需要。 HTTP 通道指定应使用超文本传输协议来传递消息。 同理,TCP 通道指定 TCP 协议。 事务流通道控制已经过事务处理的消息模式。 通过命名管道通道可以进行进程间通信。 使用 MSMQ 通道可以与 MSMQ 应用程序进行互操作。

Activation and Hosting(激活和承载)

WCF服务的最终形式仍然是程序,它能够"自承载",也可以寄宿到其它应用程序之中 ,如IIS,Windows激活服务,Com+等。

 

创建一示例程序,并对其按架构图进行解析

创建一个最简单的WCF服务,并利用上述的架构对其解析

打开vs2008,创建一个Wcf Application,命名为WcfSample1 ,如下图所示:

我们就利用系统模板产生的文件来进行解析,完成上步中,会自动产生如下的项目:

打开IService.cs,

为了简单的阐述MessageContract,我们新建一个CustomMessage.cs,代码如下:

为使用该服务,我们再创建一个ServiceContract接口和其具体实现,分别为:IMessagingHello.cs和MessageHello.svc

在web.config作如下的配置:

创建一个客户端应用项目Client用于消费上面创建的服务,创建项目后,添加Service引用,如下图所示:

分别添加对MessageHello.svc和Service1.svc的引用后,在programe.cs中添加如下代码:

用tcpTrace来监听自定义报文,可以得到

发送的消息报文为:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><HelloGreetingMessage xmlns="http://tempuri.org/"><Salutations xmlns="http://jillzhang.cnblogs.com">jillzhang</Salutations></HelloGreetingMessage></s:Body></s:Envelope>

而接受到消息报文为:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><h:OutOfBandData s:mustUnderstand="1" xmlns:h="http://jillzhang.cnblogs.com">Served by object 63334862.</h:OutOfBandData></s:Header><s:Body><HelloResponseMessage xmlns="http://tempuri.org/"><ResponseToGreeting xmlns="http://jillzhang.cnblogs.com">Service received: jillzhang</ResponseToGreeting></HelloResponseMessage></s:Body></s:Envelope>

从而可知MessageContract已经起了作用。

有关如何用tcpTrace监视消息报文,参见:http://www.cnblogs.com/artech/archive/2007/06/14/782845.html

 

本文参考文章

  1. http://www.cnblogs.com/artech/archive/2007/06/14/782845.html
  2.  

本文示例项目

  1. 服务端和客户端: /Files/jillzhang/WcfSample1.rar
  2. 自定义消息的log文件: /Files/jillzhang/cumtommsg.txt
作者:jillzhang
出处:http://jillzhang.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
标签: WCF, 架构
posted @ 2008-02-16 21:59 Robin Zhang 阅读(21475) 评论(37) 编辑 收藏

 回复 引用 查看   
#1楼[楼主] 2008-02-16 22:06 jillzhang      
有点长,累死我了
没检查错别字,有点头晕了
声明:这是入门文章,简单介绍而已,欢迎大家指教。

 回复 引用 查看   
#2楼 2008-02-16 22:52 Eeyore      
支持~
 回复 引用 查看   
#3楼 2008-02-16 23:22 KevinLi      
还来不及学,先留个记号
 回复 引用 查看   
#4楼 2008-02-16 23:39 Zhuang miao      
从顶上拖到底下都花了大半天..哈哈
 回复 引用   
#5楼 2008-02-16 23:57 深圳SEO[未注册用户]
太长了
收藏慢慢看
http://***/

 回复 引用   
#6楼 2008-02-17 00:02 新手123[未注册用户]
能总结一下说说吗。。。新手看有点长
 回复 引用 查看   
#7楼 2008-02-17 00:28 fox23      
不错~
期待下一篇~

 回复 引用 查看   
#8楼 2008-02-17 00:36 Jeffrey Zhao      
这篇好,先收藏了,呵呵。
 回复 引用 查看   
#9楼[楼主] 2008-02-17 07:34 jillzhang      
@Eeyore
@Jeffrey Zhao
@fox23
@深圳SEO
@Zhuang miao
@KevinLi
多谢支持

@新手123
可以先看看前面5篇,后面有关WCF的会越来越深入

 回复 引用   
#10楼 2008-02-17 08:15 99tte[未注册用户]
很实用,谢谢了……
 回复 引用 查看   
#11楼 2008-02-17 12:27 carysun      
wcf和wf一直不知道该学哪个
 回复 引用 查看   
#12楼[楼主] 2008-02-17 20:53 jillzhang      
@carysun
二者没有太大的联系吧?
WCF是通讯的
WF是工作流的

 回复 引用 查看   
#13楼[楼主] 2008-02-17 20:54 jillzhang      
@99tte
多谢支持

 回复 引用 查看   
#14楼 2008-02-18 06:48 carysun      
@jillzhang
这个我知道,只是时间的关系没那么多精力

 回复 引用 查看   
#15楼[楼主] 2008-02-18 08:47 jillzhang      
@carysun
那学习哪一个,主要看你的兴趣了

 回复 引用 查看   
#16楼 2008-02-18 08:52 carysun      
我做domino上workflow的,该学wf,但好像说wf不怎么成熟
 回复 引用 查看   
#17楼 2008-03-12 10:34 斧头帮少帮主      
您好,请问一下添加引用时那个端口号【2399】是怎么设置的?
好像是自动生成的,怎么调整这个端口号呢?
Config里貌似可以设置【可惜鸟用不管】
<services>
<service name="Service.Service1" behaviorConfiguration="Service.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8081"/>
</baseAddresses>
</host>
</service>
</services>

 回复 引用 查看   
#18楼[楼主] 2008-03-12 11:30 jillzhang      
@斧头帮少帮主
你可以看一下http://www.cnblogs.com/jillzhang/archive/2008/01/30/1059169.html
WCF中的地址在用途上分两种
1)用于标示服务在哪里?这个通过baseAddresses和endpoint的address来确定
2)用于标示服务的描述在哪里?这个通过serviceMetadata来设置

 回复 引用 查看   
#19楼[楼主] 2008-03-12 11:30 jillzhang      
@斧头帮少帮主
而你说的情形要利用第二种地址,此地址非彼地址

 回复 引用   
#20楼 2008-03-23 21:26 刘先生[未注册用户]
我在WCF里引入的服务 我都看不懂
我自己根据生成的类瞎写的代码 不知道你能不能看明白
ServiceReference1.IpAddressSearchWebServiceHttpPost whp = new ServiceReference1.IpAddressSearchWebServiceHttpPostClient();
ServiceReference1.getGeoIPContextRequest1 iprequest=new MyDemo.ServiceReference1.getGeoIPContextRequest1();
ServiceReference1.getGeoIPContextResponse ipresponse=new MyDemo.ServiceReference1.getGeoIPContextResponse();

whp.BegingetGeoIPContext(iprequest,,AsyncCallback callback,object asyncState)
请问那个异步回调方法怎么写? 那个 object asyncState又是什么?
能给我讲讲怎样具体实现吗?
还有个whp.EndgetGeoIPContext(IAsyncResult result);方法 谢谢啊 呵呵
如果有源代码可以发我信箱 kan_liu_xing@yahoo.com.cn

 回复 引用 查看   
#21楼[楼主] 2008-03-28 09:23 jillzhang      
 回复 引用 查看   
#22楼 2008-04-28 11:07 镜涛      
开始学习。支持
 回复 引用 查看   
#23楼 2008-05-15 22:35 高海东      
写的非常好 支持
 回复 引用   
#24楼 2008-07-04 09:04 位绰[未注册用户]
不错不错
 回复 引用   
#25楼 2008-10-14 23:22 mylittleflower[未注册用户]
太好了,感谢楼主的辛勤劳动!
建议楼主以后举的例子能像artech的文章中那样,以一个calculator为例,看起来更有实际体验,领悟得也深刻些。

 回复 引用   
#26楼 2008-10-30 22:26 lailai[未注册用户]
怎么我把"http://jillzhang.cnblogs.com"改成其它地址就不行了。有什么玄机吗?:)
 回复 引用 查看   
#27楼 2008-10-31 11:35 田朱敏      
ServiceReference2.IService1 se = new ServiceReference2.Service1Client();
string aa = se.GetData(2);
Console.WriteLine(aa);



ServiceReference1.HelloGreetingMessage greetingMsg=new ConsoleApplication1.ServiceReference1.HelloGreetingMessage();
ServiceReference1.IMessageHello ms = ServiceReference1.MessageHelloClient;
ServiceReference1.HelloResponseMessage response = ms.Hello(greetingMsg);
Console.WriteLine(response.ResponseToGreeting);
Console.WriteLine(response.OutOfBandData);
Console.Read();

怎么ServiceReference2.Service1Client();有效
我的MessageHelloClient() 无效哦

 回复 引用   
#28楼 2008-10-31 21:57 lailai[未注册用户]
@田朱敏
MessageHelloClient
是ServiceReference1的呀。

 回复 引用 查看   
#29楼 2008-11-03 22:12 zhichiyan      

创建一个服务,然后在client中“添加服务引用”进行使用吗?
为什么有的地方说要host后,客户端才能使用呢?

没搞明白,指教一下,谢谢

 回复 引用 查看   
#30楼 2008-12-13 23:33 joylee      
看了楼主这个系列的几篇文章,写的很好,非常适合我们这些初学者,虽然还是没有完全看懂,先过一遍,有时间了再看
间谍的那个例子很好哦,看了就明白了

 回复 引用   
#31楼 2009-02-02 15:37 lcn[未注册用户]
非常好支持,更希望能讲一下WEB的界面上的开发

 回复 引用   
#32楼 2009-03-02 17:33 vachel[未注册用户]
看起来有点模糊,不过基本用法会了
 回复 引用 查看   
#33楼 2009-08-05 11:14 一扬      
能不能把字搞到前面的文章那么大 看起来舒服点
 回复 引用 查看   
#34楼 2010-11-16 16:16 草珊瑚      
这个怎么没宿主
 回复 引用 查看   
#35楼 2010-11-30 21:26 五子登科      
@草珊瑚
通俗的讲服务有两两种寄存方式:一种是通过iis,一种是exe程序。本例中的服务时通过iis管道