1、概念
WCF是基于Windows平台下开发和部署服务的软件开发包。WCF为服务提供了运行时环境(Runtime Enviroment),使得开发者能够将CLR类型公开为服务,又能够以CLR类型的方式使用服务。创建服务不一定需要WCF,但使用WCF可以使得创建服务的任务事半功倍。WCF是微软对一系列产业标准定义的实现,包括服务交互、类型转换、封送(Marshaling)以及各种协议的管理。WCF还为开发者提供了大多数应用程序都需要的基础功能模块。如:托管(Hosting),服务实例管理(Service Instance Management)、异步调用、可靠性、事务管理、离线队列调用(Disconnected Queued Call)、安全性等。WCF的大部分功能都包含在一个单独的程序集System.ServiceModel.dll中,命名空间为:System.ServiceModel。
2、服务
服务是一组功能的集合,服务可以是本地的,也可以是远程的,可以有多个参与方使用任意技术进行开发。服务与版本无关,甚至可以在不同的时区同时执行。服务内部包含了语言、技术、平台、版本、框架的诸多概念,服务之间的交互只允许制定的通信模式。服务的客户端只是使用服务功能的一方。
WCF中的所有消息都是SOAP消息。消息与传输协议无关。因为服务的创建对外界而言是不透明的,所以WCF服务通常以公开元数据(Metadata)的方式描述可用的功能以及服务可能采用的通信方式。一个非WCF客户端可以将元数据作为本地类型导入到本地环境中,WCF客户端也可以导入非WCF服务的元数据,然后以本地CLR类与接口的方式进行调用。
WCF不允许客户端直接与服务交互。客户端总是使用代理(Proxy)将调用转发给服务。代理公开的操作与服务相同,同时还增加了一些管理代理的方法。WCF允许客户端跨越执行边界与服务通信。在同一台机器中,客户端可以调用同一个应用程序域中的服务,也可以在同一个进程中跨应用程序域中调用,甚至跨进程调用。客户端也可以跨越Intranet或Internet的边界与服务交互。
3、位置透明度
WCF与其他分布式技术一样要求客户端保持一致的编程模型,而不用考虑服务的位置,但实现方式却不同。即使对象是本地的,WCF仍然使用远程编程模型的实例化方式,并使用代理。由于所有的交互操作都经由代理完成,要求相同的配置与托管方式,所以对于本地和远程方式而言,WCF都只需要维持相同的编程模型。这使得开发者不会因为服务位置的改变影响客户端,同时还大大简化了应用程序的编程模型。
4、地址
WCF的每一个服务都有一个唯一的地址(Address)。地址包含两个重要元素:服务位置与传输协议(Transport Protocol)。服务位置包括目标机器名、站点或网络、通信端口、管道或队列以及一个可选的特定路径或者URI。
五种传输样式:HTTP、TCP、Peer network(对等网)、IPC(基于命名管道的内部进程通信)、MSMQ。
net.tcp://localhost:8002/Myservice
net.pipe://localhost/Mypipe
net.msmq://localhost:8002/MyService
5、契约
WCF所有的服务都公开为契约(Contract)。契约与平台无关。
四种契约:
服务契约(Service Contract):服务契约描述了客户端能够执行的服务操作。
数据契约(Data Contract):数据契约定义了与服务交互的数据类型。
错误契约:(Fault Contract):错误契约定义了服务抛出的错误。
消息契约:(Message Contract):消息契约允许服务直接与消息交互。
服务契约
ServiceContract特性公开了CLR接口(或类)作为WCF契约。WCF契约与类型的访问限定无关,因为类型的访问限定属于CLR的概念。
OperationContract特性公开了WCF服务契约中的方法,此特性只能被应用在方法上,而不允许应用到同样属于CLR概念的属性、索引器和事件上。WCF只能识别作为逻辑功能的操作(Operation)。
契约操作不允许使用引用对象作为参数,只允许使用基本类型或数据契约。
服务的类要避免使用带参数构造函数,因为WCF只能使用默认构造函数。同样,虽然类可以使用内部的属性、索引器、静态成员等,但WCF客户端却无法使用它们。
7、托管(Host)
WCF服务类不能凭空存在,每个WCF服务都必须托管(Hosting)在Windows进程中,该进程被称为宿主进程(Host Process)。单个宿主进程可以托管多个服务,而相同的服务类型也能够托管在多个宿主进程中。
三种托管方式:
IIS:只适用于HTTP协议,优势是宿主进程可以在客户端提交第一次请求的时候自动启动。
WAS:vista的windows激活服务。WAS与IIS的主要区别是WAS并不局限于HTTP,它可以支持所有可用的WCF传输协议。
自托管:自己编写Console或者Winform、Windows服务等进行宿主进程的生命周期管理。进程必须在客户端调用之前运行。宿主进程必须在运行时显式的注册服务类型,同时打开宿主。
ServiceHost类用来创建宿主。每个ServiceHost实例都与特定的地服务类型有关,如果宿主进程需要运行多个服务类型,则必须创建与之匹配的多个ServiceHost实例,主线程可以调用Open和Close方法控制宿主。打开宿主时,将装载WCF运行时,启动工作线程监控传入的请求。由于引入了工作线程,因此可以进程的主线程在打开宿主之后执行阻塞(blocking)操作。
我们也可以针对相同的类型注册多个宿主,只要这些宿主使用不同的基地址。
ServiceHost实现了ICommunicationObject接口。如果打开或关闭宿主的操作耗时比较长,可以采用异步方式调用Beginopen和Beginclose方法。
8、绑定
单个服务可以支持各个地址上的多个绑定,WCF定义了9种标准邦定。
9、终结点(endpoint)
WCF用终结点表示这样一种组成关系。终结点就是地址、契约、绑定的混成品。地址定义了服务的位置,绑定定义了服务通信的方式,契约则定义了服务的内容。每一个终结点都包含了这三个元素,而宿主则负责公开终结点。从逻辑上讲,一个接口就相当于一个终结点。每个服务必须至少公开一个业务终结点,每个终结点有且只能拥有一个契约。服务上的所有终结点都包含了唯一的地址,而一个单独的服务可以公开多个终结点。这些终结点可以使用相同或不同的邦定,公开相同或不同的契约。每个服务提供的不同终结点之间绝对没有任何关联。
可以通过管理方式(Administratively)使用配置文件或者通过编程方式(Programmatically)配置终结点。
10、元数据交换
服务有两种方案可以发布自己的元数据。一种是基于Http-Get协议提供元数据。另一种是使用专门的终结点MEX。
11、客户端编程
若要调用服务的操作,客户端首先需要导入服务契约到客户端的本地描述(Native Representation)中。如果客户端使用WCF,调用操作的常见方法是使用代理。代理是一个CLR类。如果服务支持多个契约,客户端则需要一个代理对应多个契约类型。代理不仅提供了与服务契约相同的操作,同时还包括管理对象生命周期的方法,以及管理服务连接的方法。代理完全封装了服务的每个方面:服务的位置、实现技术、运行时平台、通信传输。
12、客户端配置
客户端信息与从服务的终结点获取的信息完全相同。可以通过管理方式和编程方式实现客户端配置。建议永远不要用SvcUtil工具生成配置文件。因为它会自动的为关键的邦定节设置默认值,反而导致了整个配置文件的混乱。
WCF提供了配置文件编辑器:SvcConfigEditor。
13、代理
代理类派生自ClientBase<T>类。ClientBase<T>类通过泛型类型参数识别代理封装的服务契约。此类中的Channel属性类型就是泛型参数的类型。ClientBase<T>的子类通过Channel调用它指向的服务契约的方法。Channel对象就是相当于服务契约的代理对象,通过它,就可以调用服务契约的相关方法。
最佳的做法是在客户端调用代理完毕后要关闭代理。因为关闭代理会终止于服务的会话,关闭连接。
14、调用超时
WCF客户端的每次调用都必须在配置的超时值内完成。无论何种原因,一旦调用时间超出该时限,调用就会被取消,客户端会收到一个TimeOutException异常。可以通过修改binding的Sendtimeout属性来修改超时值。
15、编程方式配置和管理方式配置
两种技术各有所长,相符相成。管理配置方式允许开发者在部署服务之后,修改服务与客户端的主要特性,而不需要重新编译或重新部署。主要缺陷是不具备类型安全,只有在运行时才能发现配置的错误。
如果要求配置的决策完全是动态的,就可以采用编程配置的方式。他可以在运行时基于当前的输入或条件对服务的配置进行处理。