1. WCF简介
WCF(Windows Communication Foundation)是基于Windows平台下开发和部署服务的软件开发包。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案,且能与已有系统兼容协作。WCF是微软分布式应用程序开发的集大成者,它整合了.Net平台下所有的和分布式系统有关的技术,例如.Net Remoting、ASMX、WSE和MSMQ。以通信(Communiation)范围而论,它可以跨进程、跨机器、跨子网、企业网乃至于 Internet;以宿主程序而论,可以以ASP.NET,EXE,WPF,Windows Forms,NT Service,COM+作为宿主(Host)。WCF可以支持的协议包括TCP,HTTP,跨进程以及自定义,安全模式则包括SAML, Kerberos,X509,用户/密码,自定义等多种标准与模式。也就是说,在WCF框架下,开发基于SOA的分布式系统变得容易了,微软将所有与此相关的技术要素都包含在内,掌握了WCF,就相当于掌握了叩开SOA大门的钥匙。
2. 服务
服务(Services )是公开的一组功能的集合。一个面向服务应用程序(SOA)将众多服务聚集到单个逻辑的应用程序中,这就类似于面向组件的应用程序聚合组件,或者面向对象的应用程序聚合对象,如图 1.1-1 所示:
图 1.1-1
服务可以是本地的,也可以是远程的,可以由多个参与方使用任意技术进行开发。服务与版本无关,甚至可以在不同的时区同时执行。服务内部包含了诸如语言、技术、平台、版本与框架等诸多概念,而服务之间的交互,则只允许指定的通信模式。
客户端与服务通过消息的发送与接收进行交互。消息可以直接在客户端与服务之间进行传递,也可以通过中间方进行传递。WCF 中的所有消息均为 SOAP 消息。注意 WCF 的消息与传输协议无关,这与 Web 服务不同。因此,WCF 服务可以在不同的协议之间传输,而不仅限于 HTTP。WCF 客户端可以与非 WCF 服务完成互操作,而 WCF 服务也可以与非 WCF 客户端交互。不过,如果需要同时开发客户端与服务,则创建的应用程序两端都要求支持WCF,这样才能利用 WCF 的特定优势。
WCF不允许客户端直接与服务交互,即使它调用的是本地机器内存中的服务。相反,客户端总是使用代理(Proxy)将调用转发给服务。WCF 允许客户端跨越执行边界与服务通信。在同一台机器中,客户端可以调用同一个应用程序域中的服务,也可以在同一进程中跨应用程序域调用,甚至跨进程调用,如图 1.1-2 所示:
图 1.1-2
客户端也可以跨越 Intranet 或 Internet 的边界与服务交互,如图 1.1-3 所示。
图 1.1-3
3. 地址
WCF 的每一个服务都具有一个唯一的地址(Addresses)。地址包含两个重要元素:服务位置与传输协议(Transport Protocol),或者是用于服务通信的传输样式(Trans portSchema)。
服务位置包括目标机器名、站点或网络、通信端口、管道或队列,以及一个可选的特定路径或者 URI。URI 即统一资源标识 (Universal Resource Identifier),它可以是任意的唯一标识的字符串,例如服务名称或 GUID。
WCF 1.0 支持下列传输样式:
- HTTP
- TCP
- Peer network(对等网)
- IPC(基于命名管道的内部进程通信)
- MSMQ
TCP 地址采用 net .tcp 协议进行传输,如果没有指定端口号,则 TCP 地址的默认端口号为 808,如:net.tcp://localhost/MyService。两个相同宿主的 TCP 地址可以共享一个端口。
HTTP 地址使用 http 协议进行传输,通常会被用作对外的基于 Internet 的服务,并为其指定端口号,例如:http://localhost:8001。如果没有指定端口号,则默认为 80 。与 TCP 地址相似,两个相同宿主的 HTTP 地址可以共享一个端口,甚至相同的机器。
IPC 地址使用 net.pipe 进行传输,这意味着它将使用 Windows 的命名管道机制。在WCF中,使用命名管道的服务只能接收来自同一台机器的调用。因此,在使用时必须指定明确的本地机器名或者直接命名为 localhost,为管道名提供一个唯一的标识字符串:net.pipe://localhost/MyPipe每台机器只能打开一个命名管道,因此,两个命名管道地址在同一台机器上不能共享一个管道名。
MSMQ 地址使用 net. msmq 进行传输,使用微软消息队列(Microsoft Message Queue,MSMQ)机制。使用时必须为 MSMQ 地址指定队列名。如果是处理私有队列,则必须指定队列类型,但对于公有队列而言,队列类型可以省略:
net.msmq://localhost/private/MyService
net.msmq://localhost/MyService
对等网地址(Peer Network Address) 使用 net.p2p 进行传输,它使用了 Windows 的对等网传输机制。
4. 契约
WCF 的所有服务都会公开为契约(Contract)。契约与平台无关,是描述服务功能的标准方式。WCF 定义了四种类型的契约:
- 服务契约(Service Contract):服务契约描述了客户端能够执行的服务操作。
- 数据契约(Data Contract):数据契约定义了与服务交互的数据类型。WCF 为内建类型如 int 和 string 隐式地定义了契约;我们也可以定制类型定义为数据契约。
- 错误契约(Fault Contract):错误契约定义了服务抛出的错误,以及服务处理错误和传递错误到客户端的方式。
- 消息契约(Message Contract):消息契约允许服务直接与消息交互。消息契约可以是类型化的,也可以是非类型化的。如果系统要求互操作性,或者遵循已有消息格式,那么消息契约会非常有用。
ServiceContract 特性可以将一个 CLR 接口(或者通过推断获得的接口)映射为与技术无关的服务契约。ServiceContract 特性公开了 CLR 接口(或者类)作为 WCF 契约。WCF 契约与类型的访问限定无关,因为类型的访问限定属于 CLR 的概念。即使将 ServiceContract 特性应用在内部( Internal)接口上,该接口同样会公开为公有服务契约,以便于跨越服务边界实现服务的调用。如果接口没有标记 ServiceContract 特性,WCF 客户端则无法访问它(即使接口是公有的)。这一特点遵循了面向服务的一个原则,即明确的服务边界。为满足这一原则,所有契约必须明确要求:只有接口(或者类)可以被标记为 ServiceContract 特性,从而被定义为WCF 服务,其他类型都不允许。
即使应用了ServiceContract特性,类型的所有成员也不一定就是契约中的一部分。我们必须使用 OperationContractAttribute 特性显式地标明哪些方法需要暴露为WCF契约中的一部分。
5. 托管
WCF服务类不能凭空存在。每个WCF服务都必须托管(Hosting) 在 Windows 进程中,该进程被称为宿主进程(Host Process)。单个宿主进程可以托管多个服务,而相同的服务类型也能够托管在多个宿主进程中。WCF 没有要求宿主进程是否同时又是客户端进程。显然,一个独立的进程有利于错误与安全的隔离。
- IIS 托管: Internet 信息服务器(Internet Information Server,IIS)托管服务。主要的优势是宿主进程可以在客户端提交第一次请求的时候自动启动,还可以借助 IIS 管理宿主进程的生命周期。IIS 托管的主要缺点在于只能使用 HTTP 协议。如果是 IIS 5,还要受端口限制,要求所有服务必须使用相同的端口号。
- 自托管(Self-Hosting):由开发者提供和管理宿主进程的生命周期。自托管方式适用于如下场景:需要确定客户端与服务之间的进程(或机器)边界时;使用进程内托管 ,即服务与客户端处于相同的进程中时。进程可以是任意的 Windows 进程,例如Windows 窗体应用程序、控制台应用程序或 Windows NT 服务。注意,进程必须在客户端调用服务之前运行,这意味着通常必须预先启动进程。但 NT 服务或进程内托管不受此限制。
- WAS 托管: Windows 激活服务(WAS)是一个系统服务,只适用于 Windows Vista。W AS 提供了大量基于自托管的强大功能,包括应用程序池、回收机制、空闲时间管理(Idle Time Management)、 身份管理(Identity Management) 以及隔离(Isolation);
6. 绑定
WCF 通信模式与交互方式之间的组合,数量可能达到上千万。在这些组合选项中,有的可能是互斥的,有的则彼此约束。为了简化这些选项,WCF 引入了绑定(Binding )技术将这些通信特征组合在一起。
WCF 定义了9种标准绑定:
- 基本绑定(Basic Binding):由BasicHttpBinding类提供。基本绑定能够将WCF服务公开为旧的ASMX Web服务,使得旧的客户端能够与新的服务协作。如果客户端使用了基本绑定,那么新的 WCF 客户端就能够与旧的 ASMX 服务协作。
- TCP 绑定 :由 NetTcpBinding 类提供。TCP 绑定使用 TCP 协议实现在 Intranet 中跨机器的通信。TCP 绑定支持多种特性,包括可靠性、事务性、安全性以及 WCF 之间通信的优化。前提是,它要求客户端与服务都必须使用 WCF。
- 对等网绑定 :由 NetPeerTcpBinding 类提供。它使用对等网进行传输。
- IPC 绑定 :由NetNamedPipeBinding类提供。它使用命名管道为同一机器的通信进行传输。这种绑定方式最安全,因为它不能接收来自机器外部的调用。IPC 绑定支持的特性与 TCP 绑定相似。
- Web 服务(WS)绑定 :由WSHttpBinding类提供。WS绑定使用HTTP或 HTTPS进行传输,为基于Internet的通信提供了诸如可靠性、事务性与安全性等特性。
- WS 联邦绑定(Federated WS Binding):由 WSFederationHttpBinding 类提供。
- WS 双向绑定(Duplex WS Binding):由 WSDualHttpBinding 类提供。WS 双向绑定与 WS 绑定相似,但它还支持从服务到客户端的双向通信。
- MSMQ 绑定 :由 NetMsmqBinding 类提供。它使用 MSMQ 进行传输,用以提供对断开的队列调用的支持。
- MSMQ 集成绑定(MSMQ Integration Binding ):由 MsmqIntegrationBinding 类提供。
每种标准绑定使用的传输协议与编码格式都不相同,如图 1.1-4 所示:
图 1.1-4
如何选择绑定,如图 1.1-5 所示:
图 1.1-5
7. 终结点
服务与地址、绑定以及契约有关。其中,地址定义了服务的位置,绑定定义了服务通信的方式,契约则定义了服务的内容。每一个终结点都包含了三个元素,而宿主则负责公开终结点,如图 1.1-6 所示:
图 1.1-6
每个服务至少必须公开一个业务终结点,每个终结点有且只能拥有一个契约。服务上的所有终结点都包含了唯一的地址,而一个单独的服务则可以公开多个终结点。这些终结点可以使用相同或不同的绑定,公开相同或不同的契约。每个服务提供的不同终结点之间绝对没有任何关联。
8. 可靠性
WCF 与其他面向服务技术之间最大的区别在于传输可靠性(Transport Reliability)与消息可靠性(Message Reliability)。
传输可靠性(例如通过 TCP 传输)在网络数据包层提供了点对点保证传递(Point-to-Point Guaranteed Delivery),以确保数据包的顺序无误。传输可靠性不会受到网络连接的中断或其他通信问题的影响。
消息可靠性负责处理消息层的可靠性,它与传递消息的数据包数量无关。消息可靠性提供了端对端保证传递(End-to-End Guaranteed Delivery),确保消息的顺序无误。消息可靠性与引入的中间方的数量无关,与网络跳数(Network Hops)的数量也没有关联。消息可靠性基于一个行业标准。该行业标准为可靠的基于消息的通信维持了一个在传输层的会话。如果传输失败,例如无线连接中断,消息可靠性就会提供重试(Retries)功能。它还能够自动处理网络阻塞(Congestion)、消息缓存(MessageBuffering)以及流控制(Flow Control),根据具体情况适时调整发送的消息数。消息可靠性还能够通过对连接的验证管理连接自身,并在不需要连接时清除它们。消息可靠性确保了消息的有序传递,允许消息按照发送顺序而非接收顺序执行。 此外,它保证了消息只会被传递一次。WCF 允许开发者只启用可靠性,而不启用有序传递。此时,消息按照接收它们的顺序进行传递。如果同时启用了可靠性与有序传递,则所有绑定的默认值均支持可靠性。
WCF 的 可靠性是在绑定中控制与配置的。一个特定的绑定可以支持可靠消息传输(Reliable Messaging),也可以不支持它。如果支持,也可以通过设置为启用或禁用。何种绑定支持何种可靠性值,要根据绑定的目标场景而定。
如图 1.1-7 所示:
图 1.1-7