(1):揭开神秘面纱
引子
WCF是"Windows Communication Foundation "的缩写,原来的代号为"Indigo",它是MS为SOA(Service
Oriented Architecture)而设计的一套完整的技术框架。利用它能够开发出分布式(Distributed)应用程序,而且开发难度相比以前的.Net
Remoting和Asp.Net Xml Web Service等都有了大幅度的降低。可以说WCF是目前微软平台下最先进的SOA框架,也是微软在今后一段时间内在该领域的主打产品。它具有很多优点,但本人总结起来,其最大的特征在于1)充分整合了原来的.Net
Remoting,Asp.Net Xml Web Service,MSMQ,WSE,Enterprise
Service等多项分布式技术,取其精华,弃其糟粕。2)WCF虽然整合了几项技术,但开发难度不增反降,简单易学。相信在未来的几年中,WCF一定在SOA的大潮中披荆斩棘,大展身手。本系列文章从大的方向上分为两个部分,第一部分是介绍WCF相关的理论知识,第二部分是用WCF来开发一个完整的项目实例。希望在理论和实践上和大家一起学习微软这个优秀的框架。
本文的出发点和目的
通过阅读本文,能解决以下几个问题
WCF是什么?
WCF能干什么?
WCF的今生前世?
学习WCF有哪些资源?
本文适合的读者
对WCF感兴趣的初学者,最好以前有一些SOA相关的基础常识。
WCF是什么?
比较贴近官方的说法是:WCF(原代号为Indigo)是一个用于创建和运行分布式系统的技术集合,使用它能创建安全的(Secure)、可靠的(Reliable)、跨平台的(transacted
messaging along with interoperability)的分布式解决方案。它的面向服务的编程模型整合了.Net平台下以往全部的分布式开发技术,例如.Net
Remoting,Asp.Net Xml Web Service,MSMQ,WSE,和Enterprise
Service等,它可以支持跨应用程序域(AppDomain),进程(Process),网络(NetWork)的进行数据通讯,而且能寄宿在诸如IIS,Windows
Service,Console,Windows Application等多种宿主(Host)中。它适用于Vista,Xp和Windows
2003等操作系统。是微软在SOA领域推出的一款主打产品。有关详细介绍,请参见WCF官方主页:http://netfx3.com/content/WCFHome.aspx
WCF能干什么?
在win32中,应用程序是运行在进程(Process)的线程(Thread)中的,.Net平台出现之后,出现了AppDomain,其实就相当于在进程和线程之间又有了一层包装,类似于子进程的概念,在一个进程(或者应用程序域)中的对象能进行直接的访问和控制,但超出这个范围,便不能进行直接的访问和控制了,所以说进程(或者应用程序域)有一定的隔离作用,如果是分布在不同网络,不同操作系统上的不同进程,他们进行通讯的难度就更大,而分布式应用程序要求的就是将原本被隔离的作用域通过一定的契约联系起来,从而达成多个系统的沟通协作。当然能实现这种目的的方式远不止WCF一个,比如在win32时代,经常使用映射内存文件来实现进程之间的互操作问题,还有在windows程序中,用windows消息wm也能实现不同进程之间的通讯问题,但这些都有局限性,因为他们不能很好的解决跨平台,跨网络问题,而WCF可以。
WCF的今生前世
早在Web Service出现之前,已经有很多企业都实现了自己的EAI(Enterprise Application
Integration)企业应用整合,但此时并没有被大家所公认的技术规范,所以那时的集成方案比较分散,没有统一标准,尽管有些EAI做得还比较成功,苦于没有技术规范,很难得以推广。而出现Web
Service后,由于更大厂商(包括IBM,MS等)的大力支持,Soap成为大家所公认的技术规范,很快就成为了解决这一难题的制胜法宝。MS为响应这种变化,在.Net平台中推出了自身的Web
Service产品,也就是Asp.Net Xml Web Service,但这个框架在通讯安全和性能等方面存在着一些难以解决的问题,虽然后来又增加了WSE来弥补不足,但整体看来,Asp.Net
Xml Web Service的不足还是显而易见的。在安全方面,WSE对Xml Web Service作了很大的改进,支持ws等网络服务的安全标准,但它作为框架的扩展,最新版本3.0还在beta阶段,而且这个扩展框架鲜为人知,服务端如果使用了WSE,那也要求客户端使用,而由于这个框架没有被广泛的推广,很可能给对客户端开发人员增加开发和部署难度。在性能方面,.Net
Remoting技术相比Web Service略有优势,但学起来有一定难度,最要命的是它不能实现跨平台的操作,一个用.Net
Remoting写的Service很难用Java来调用,这就使得其实用性大打折扣,MSMQ支持消息队列,但需要整合在其他系统之中,传统的Enterprise
Service支持分布式事务,但同样没有Web Service的跨平台特性。此时,WCF应运而生,它整合了MS历来最优秀的分布式系统开发技术,取其精华,弃其糟粕,是分布式应用程开发技术的集大成者,它解决了跨平台的问题,同时支持安全通讯和分布式事务。由于其简单易学,在推广上也必然比较顺利,可以说WCF将开辟分布式开发技术的一个新纪元,其影响应该不在当年Web
Service之下。
(2):决战紫禁之巅
本文的出发点
通过阅读本文,能解决如下问题:
- WCF与以往的分布式技术有何区别?
- WCF 在安全性方面做了哪些改进?
- WCF在性能方面有那些改进?
- WCF开发模型和以往的其他分布式技术有何区别?
本文适合的读者
有过分布式开发和SOA相关实施经验的开发人员
WCF与以往的分布式技术有何区别?
在上篇文章 WCF从理论到实践一:揭开神秘面纱
中曾经阐述过WCF的前生今世,说的比较概括,本文详细的说明WCF和以往的分布式技术的区别,目的是让大家更详细的了解WcF的应用场合,为日后系统的架构作铺垫。首先先看下面这张对比表格
WCF与其他分布式技术对比表
|
Xml
Web Service |
.Net
Remoting |
Enterprice
Service |
WSE
|
MSMQ |
WCF |
跨平台 |
√ |
|
|
|
|
√ |
.Net与.Net通讯 |
|
√ |
|
|
|
√ |
分布式事务 |
|
|
√ |
|
|
√ |
安全可靠性 |
|
|
|
√ |
|
√ |
消息队列 |
|
|
|
|
√ |
√ |
上面的表格参考了Bruchzhang文章中的对比图,原文地址:
http://www.cnblogs.com/wayfarer/archive/2006/04/05/367474.html
从表格中我们可以看出,WCF似乎等于前面几项技术之和,但事实并非如此,它既整合了原来的多项技术,而且拥有着自己得天独厚的优点,如下:
- 统一性(Integration)
- 互操作性
- 安全可靠(Secure and Reliable)
- 兼容性
WCF 在安全性方面做了哪些改进?
为了保证数据通讯的安全,WCF提供了三种保护措施:1)机密性(Confidentiality)2)完整性(Integrity)
3)可验证性(Authentication),这三种措施联合起来被称为CIA。并且这些措施在WCF中是默认支持的。机密性能保证传输的数据是经过加密的,不被非法监听(eavesdrop),而完整性利用数字签名技术防止数据在传输过程中被注入(injected)或篡改(tampered),而验证(Authentication)可以采用灵活的策略来处理达到的客户端请求,比如用户名密码验证,客户端证书验证等。为了显示WCF在安全性方面的特点和优点,我制作了演示程序:Security_Compare方案,这个方案主要通过对比wcf和xml
web service的消息来表现wcf在安全方面的改进,工程清单如下:
ProjectName(项目名称) |
Remark(备注) |
Wcf |
WCF的服务端程序,默认创建,功能未经修改 |
WcfClient |
WCF程序的客户端,用于调用Wcf |
WebService |
Xml Web Service服务程序,完成功能和Wcf一样 |
WsClient |
是Xml Web Service的客户端,用于调用WebService |
为了跟踪Web
Service和WCF的消息,我们还需要了解一下两个工具:
- Microsoft SOAP Toolkit Version
3 中的 Trace Utility
- tcpTrace
原来一直用Trace
Utilty来跟踪xml web service的消息报文,非常好用,它能按包显示出Soap信息,看起来也非常方便。有关它的消息,请从http://www.microsoft.com/downloads/details.aspx?FamilyId=C943C0DD-CEEC-4088-9753-86F052EC8450&displaylang=en
上下载SOAP Toolkit 3.0,安装后,便出现了这个工具,在跟踪xml web service的消息报文的时候,这个工具很好用,但跟踪wcf的报文却不行,能截获到数据,但每个报文都是空的,可能也和wcf报文是经过加密的有关系吧,
搜索了一下,在artech的blog中发现这么一篇文章:[原创]我的WCF之旅(9):如何在WCF中使用tcpTrace来进行Soap
Trace,解决了我不能跟踪wcf消息报文的难题,他也提到Trace Utilty不能跟踪wcf,同时建议大家使用tcpTrace,并且说明了使用方法,对tcpTrace不熟悉的同学可以到他的blog上学习,很实用,我在这里就不再赘述。
经过我的跟踪,我分别将Xml
web Service的消息log到ws.txt中,将wcf的消息log到wcf.txt中,您可以从下面的本文相关文件下载中获取这两个文件,观察二者在消息上的不同。用于演示的示例解决方案您也在相关文件下载中获得。
WCF在性能方面有那些改进?
大家都知道,越复杂,结构层次越多的框架一般效率也越低,WCF是以往其他分布式技术的集成者,它结构相对复杂,且由于默认支持安全传输,在性能上应该不如Xml
Web Service技术,更不用和.Net Remoting等比较,这是一个有框架设计经验和架构师们都明白的简单道理,但是事实怎么样呢?wcf比xml
web service性能到底是高还是底,低要低多少?这些问题很值得大家的研究和讨论,其实已经有人在此方面做了很详细的对比,msdn上便有一篇专门介绍此方面知识的文章:
WCF Performance Comparison ,对wcf性能感兴趣的同学,可以到这文章中学习。很详尽。限于条件的限制,我这里只在我一台机器上作一个简单的对比,仅供参考。分别测试循环1000次对wcf和xml
web service相同功能方法的调用,得到如下的数据:
|
WCF |
Web Service |
第一次 |
9523ms |
7561ms |
第二次 |
9480ms |
7465ms |
第三次 |
9508ms |
7708ms |
第四次 |
9487ms |
7900ms |
经过四次测试数据,我们可以得出,wcf的性能和xml
web service相比的确要低,但差别不大,肯定在一个数量级之上。有关测试性能的解决方案Perfermence_Compare您能在相关文件下载中获得。
WCF开发模型和以往的其他分布式技术有何区别?
WCF不仅仅在功能上集成了以往的分布式开发技术,而且在编程模型中充分吸取原来技术的优点,如xml
web service的声明性编程(declareable),和.net remoting中的配置(configuration)和wse中的安全策略声明性配置方法,这样wcf虽然功能强大,而且学习简单,便于推广。在vs2008中还集成了WCF
Test Client,开发服务的时候,甚至不需要再开发测试客户端就能用WCF Test Client来进行调用,简单之极,示例程序更是无需更改以行代码,便可以运行。
上面这些是说了wse编程的简单易学性,我总结出来,主要包括以下几种特性
- 基于声明性编程模型
- 充分利用配置来实现框架的灵活。
- 使用配置的同时,仍保留代码编程的模型,使得框架更加丰富,便于控制。
- 默认的CIA支持,极大地简化了安全控制
相关示例文件
- 安全对比示例解决方案Security_Compare:
/Files/jillzhang/Security_Compare.rar
- 跟踪soap消息的工具tcpTrace:
/Files/jillzhang/tcpTrace.rar
- 安全对比示例跟踪结果:
/Files/jillzhang/wcf.txt ,
/Files/jillzhang/ws.txt
- 性能测试解决方案Perfermence_Compare:
/Files/jillzhang/Perfermence_Compare.rar
示例程序和本文对比测试的平台依据
windows
xp sp2 + visual studio.net 2008 rtm
(3):八号当铺之黑色契约
本文的出发点:
通过阅读本文,能解决以下的问题
- 什么是契约?
- 契约有几种?,他们都有什么用途
- 如何定义契约?
- 契约是独立于平台的么?
- 契约和以往哪种技术比较相像,又有什么不同?
本文适合的读者
WCF的初学者,可以没有任何SOA或者其他分布式技术经验
什么是契约?
任何一个分布式应用程序,它之所以能够互相传递消息,都是事先制定好数据交换规则的,这个规则正是交换数据的双方(比如服务器端和客户端)能彼此理解对方的依据,WCF作为分布式开发技术的一种,同样具有这样一种特性。而在WCF中制定的的规则就被称之为契约(Contract),它是WCF的消息标准,是任何一个wcf程序不可或缺的一部分。
契约有几种?,他们都有什么用途
在WCF中,契约分为四种,它们分别为:
- 用于定义服务操作的服务契约:Service Contract
这种级别的契约又包括两种:ServiceContract和OperationContract
ServiceContract用于类或者结构上,用于指示WCF此类或者结构能够被远程调用,而OperationContract用于类中的方法(Method)上,用于指示WCF该方法可被远程调用。
- 用于自定义数据结构的数据契约:Data Contract
数据契约也分为两种:DataContract和DataMember.DataContract用于类或者结构上,指示
WCF此类或者结构能够被序列化并传输,而DataMember只能用在类或者结构的属性(Property)或者字段(Field)上,指示WCF该属性或者字段能够被序列化传输。
- 用于自定错误异常的异常契约:Fault Contract
FaultContract用于自定义错误异常的处理方式,默认情况下,当服务端抛出异常的时候,客户端能接收到异常信息的描述,但这些描述往往格式统一,有时比较难以从中获取有用的信息,此时,我们可以自定义异常消息的格式,将我们关心的消息放到错误消息中传递给客户端,此时需要在方法上添加自定义一个错误消息的类,然后在要处理异常的函数上加上FaultContract,并将异常信息指示返回为自定义格式。
- 用于控制消息格式的消息契约:Message Contract
简单的说,它能自定义消息格式,包括消息头,消息体,还能指示是否对消息内容进行加密和签名。
如何定义契约?
其实上面落里罗嗦说了一大堆,似乎契约使用起来应该很难的样子了,可事实上,契约的使用是很简单的,它无非就是在普通的程序结构上添加一些声明性的属性就可以了,比如我们可以直接在类上声明ServerContractAttribute,此时这个类就能被远程客户端访问到,而在类中的方法中(Method)添加OperationContractAttribute就能将方法暴露给远程客户端,其他的契约也一样的用法,比较难得还是消息契约和错误契约,当也很简单。我这里没有WCF开发环境,所以具体怎么用,我就不做示例了,您仍不明白的话,可以参考下面几篇文章:
http://www.cnblogs.com/artech/archive/2007/02/28/659331.html
http://www.rainsts.net/article.asp?id=427
http://www.rainsts.net/article.asp?id=429
http://www.rainsts.net/article.asp?id=430
他们的blog中都有较详细的阐述和使用方法说明
契约是独立于平台的么?
WCF作为一种能够跨平台的体系框架,其应用肯定会有异构,异网的情况发生,那么作为通讯依据的契约能否自动适用于上述情况呢?答案是肯定的,契约是独立于平台之外的,它只约束通讯的双方应该遵守什么样的规则,而丝毫不管双方各自采用的是什么样的技术和什么样的操作系统,也只有这样,WCF才能有真正的生命力。
契约和以往哪种技术比较相像,又有什么不同?
如果非要拿契约和以往的技术相比较的话,契约和asp.net xml web service的声明性编程模型甚是相似,比如在web
service中在类上标记WebServiceAttribute便可以将此类用于远程调用,而将方法添加WebMethondAttribute也可以将其暴露给远程客户端,这和WCF中的ServiceContract和OperationContract简直如出一辙,但不同的是,WCF中的契约要比Xml
Web Service中的要详尽的多,比如ServiceContract和OperationContract可以直接使用在接口上面,而实现该接口的类就继承了这种契约声明,自动拥有契约所规范的动作和行为,这就使得程序员更方便的使用面向接口的编程方式,可以使同一服务拥有不同的实现,在新旧版本升级的同时,能够使新老版本共同运行。
(4):路在何方
本文的出发点
通过阅读本文,您能了解以下知识:
- Address是什么?
- Address的组成?
- 如何在配置文件中指定Address?
- 如何通过编程方式设置Address?
- Address有什么特殊应用?
本文适合的读者
适合WCF初学者,可以没有任何SOA和其他分布式开发经验
Address是什么?
一个要和服务端通讯的客户端要做的第一件事情,就是搞清数据要发给谁?目的地在哪?而Address正是通过一个Uri来唯一标示一个WCF的终节点(EndPoint)的,它标示了消息发送的目的地。在WCF
数据通讯中,它解决了服务在哪里的问题。
Address的组成?
Address在WCF中的用System.ServiceModel.EndpointAddress对象来表示的,它的结构如下:
组成部分 |
作用 |
Uri |
指示EndPoint的地址,是必须的 |
Identity |
能保证地址的唯一性,当Uri一致的时候,可以用Identity来区分EndPoint,可有可无 |
Headers |
为地址提供了一些附加信息,用于Soap Message
Filter,最后会添加到Soap消息的Header中 |
此外,Address还包括IsAnonymous属性,用于指示终节点是否能匿名访问。
如何在配置文件中指定Address?
在配置文件中,有两种方式可以指定Address,一种是绝对地址方式,另外是相对地址方式,分别如下:
绝对地址
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/" />
</baseAddresses>
</host>
<endpoint address ="http://localhost:8731/Service" binding="basicHttpBinding"
contract="Wcf_Address_Config.IService1"> </endpoint>
相对地址
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/" />
</baseAddresses>
</host>
<endpoint address ="Service1" binding="basicHttpBinding" contract="Wcf_Address_Config.IService1"></endpoint>
在网上有人说绝对地址是通过将httpGetEnabled设置为true,并且设置httpGetUrl为绝对地址是在设置endPoint的说法有些不准确,因为在WCF中有两种地址,一种是访问endPoint时候用到地址,另外一种是服务描述的地址,服务描述在wcf中被称作serviceMetadata,通过它能够产生代理类,比如,我们做如下的设置:
<serviceMetadata httpGetEnabled="True" httpGetUrl="http://localhost:8731/Service"/>
只代表在http://localhost:8731/Service/?wsdl上能找到服务描述,可以通过http://localhost:8731/Service/?wsdl生成代理类,而不是将endPoint的地址设置为了http://localhost:8731/Service,这点一定要注意,不要受有些说法的误导。
如何通过编程方式设置Address?
除了能在配置中设置Address外 ,还可以通过编程的方式来设置Address,具体方法请参参见下面的代码示例:
static void Main(string[] args)
{
EndpointAddress address = new EndpointAddress("http://127.0.0.1:2136/Service1");
Binding binding = new BasicHttpBinding();
wcf.IService1 service = new wcf.Service1Client(binding, address);
Console.WriteLine(service.GetData(2));
Console.Read();
}
上面的代码就是将endPoint的地址设置为了http://127.0.0.1:2136/Service1
Address有什么特殊应用?
在wcf中,能够将服务同时发布到几个地址上面,只要这些地址采用的都是一种访问方式。这种一份程序,多个发布地址的做法,在以往的技术中是没有的。
示例项目:
通过配置文件设置Address:/Files/jillzhang/Wcf_Address_Config.rar
通过代码方式设置Address:/Files/jillzhang/Wcf_Address.rar
|