WCF - 快速回顾






4.95/5 (21投票s)
本文适合希望一次性回顾 WCF 的读者。
引言
我阅读过许多关于 WCF 的文章,但我一直在寻找一篇能够让我快速概览 WCF 所有主题的文章。本文适合希望一次性回顾 WCF 的读者。让我们从面向服务架构 (SOA) 开始,然后我们再看看 WCF。
什么是SOA?
SOA 是一种构建业务应用程序的架构风格,它使用松耦合的服务,这些服务通过链接在一起以实现特定功能。它不是一种技术或工具。SOA 将我们的思维方式从类和对象转移到服务,以及将通信机制从 HTTP 转移到消息。
关于 SOA 的要点
- SOA 将应用程序分解为服务
- 它允许不同技术的互联互通
- 它应该是耐用且安全的
- 服务和消息是SOA的构建块
- 服务 - 自我包含的业务功能
- 服务应使用消息进行通信
- 服务应自行定义
- 消息格式应为标准,例如 XML
- 消息应能够异步通信并应可靠
- 消息应能够以标准方式描述和发现服务
SOA 的优势
- 位置无关性
- 跨平台互操作性
- 类 API 的开发范例
- 比对象分发更好的组织结构
- 松耦合
- 安全
服务导向原则
- 边界是明确的
- 服务通过发送消息穿越其边界进行通信
- 所有通信都通过消息进行
- 服务是自主的
- 我们可以独立地构建、管理和版本化服务
- 只要客户端可以继续发送和接收相同的消息,我们就可以在不影响客户端的情况下更改服务
- 服务共享契约和模式
- 契约描述了服务可以发送和接收的消息
- 模式定义了客户端和服务如何构建它们交换的消息
服务和组件有什么区别?
服务用于在异构环境中进行通信。它使我们能够跨平台。组件和类将我们限制在编程边界内通信。它将我们束缚于特定的语言。
Windows Communication Foundation
WCF 在 Microsoft .NET Framework 3.0 中引入。以前称为 Indigo,它是一个统一的模型,汇集了 Web 服务、Remoting、Sockets、MSMQ 和 Enterprise Services。它强制执行 SOA 方法,并提供事务支持、安全性、持久性等。
所有与 WCF 相关的类都属于 System.ServiceModel
命名空间。
WCF 的优势
- 可靠性
- 耐用性
- 事务
- 实例管理
- 节流
- 互操作性
- 故障隔离
- 日志记录
- 跟踪
- 同步
- 错误掩盖
- 缓冲
- 版本控制
端点
与 Windows Communication Foundation (WCF) 服务的所有通信都通过服务的端点进行。端点为客户端提供了对 WCF 服务所提供功能的访问 - MSDN。
宿主应用程序通过提供一个或多个端点给客户端来使服务可用。每个端点包含三个元素:地址、绑定和契约。
地址:在 WCF 中,每个服务都有一个唯一的地址。地址包含两个重要元素
- 服务位置 - 地址的一部分指示目标计算机的名称
- 传输协议 - 示例:HTTP/HTTPS, TCP, IPC, MSMQ 等。
[基本地址] / [可选 URI]
示例:http:// localhost:8001
契约:契约是描述服务功能的一种平台无关的标准方式。WCF 定义了四种类型的契约
- 服务契约
- 它是一个接口,定义了一个与单个类型或数据契约一起工作的服务操作。
- 描述了客户端可以在服务上执行哪些操作。
[ServiceContract]
属性将一个接口标记为服务契约。[OperationContact]
属性公开接口的方法。
// Employee ServiceContract [ServiceContract] public interface IEmployeeService { // Define the GetEmpName OperationContact here…. [OperationContract] String GetEmployeeName (int empId); // Define the GetempInfo OperationContact here…. [OperationContract] StudentInformation GetEmployeeInfo (int empId); }
- 数据协定
- 定义了传递到服务和从服务传递出来的数据类型。
- 描述了 CLR 类型如何映射到 XSD 模式定义。
- WCF 为内置类型(如
int
和string
)定义了隐式契约,但您可以轻松地为自定义类型定义显式的选择加入数据契约。 - 使复杂类型能够被序列化和反序列化,以便可以传递。
- 它必须用
[Data Contracts]
装饰。 - 数据契约的每个成员都应被
[DataMember]
装饰。
[DataContract] public class EmployeeInfo { [DataMember] Public string EmpName; // Define the other Datamembers here…. }
- 故障契约
- 定义了哪些错误由服务引发,以及服务如何处理和将错误传播给其客户端。
- 我们在服务的操作上使用
FaultContact
属性。 - 使用
FaultException<T>
类返回强类型 SOAP 错误。
- 消息契约
- 它允许服务直接与消息交互。
- 它可以是类型的或非类型的。
- 消息契约在互操作性场景中很有用。
通道
- 客户端和服务通过传递消息进行通信
- 它们用于通信的机制是一个通道堆栈,该堆栈由通道组成。
绑定
- 绑定指定了客户端和 WCF 服务如何通信
- 指定客户端端点如何与服务端点通信。
- 指定客户端和服务将使用的传输协议、消息编码、安全性、事务和可靠性。
- 绑定代表通道堆栈。
- 绑定继承自
Binding
类。 - 包含描述通信某些方面的绑定元素。
- 传输(HTTP, TCP 等)
- 协议(安全性、可靠性、事务等)
- 消息编码(文本、二进制等)
- 绑定由多个绑定元素组成。
- 每个绑定元素对应通道堆栈中的一个通道。
- 绑定元素继承自
BindingElement
类。 - 可以声明式地或以编程方式创建。
WCF 中常用的绑定有
BasicHttpBinding
– 旨在将 WCF 服务公开为旧版 ASMX Web 服务。WSHttpBinding
- 它使用 HTTP 或 HTTPS 进行传输,并通过互联网提供各种功能,所有这些都使用 WS-* 标准。Visual Studio 默认使用此项。WSDualHttpBinding
– 支持 WS-* 以及双向通信。NetTcpBinding
– TCP 绑定用于内网上的跨机器通信。它支持多种功能,包括可靠性、事务和安全性。它针对 WCF 到 WCF 的通信进行了优化。NetNamedPipeBinding
– 此绑定用于进程间通信 (IPC)。它使用命名管道作为传输,用于同一机器通信。它是最安全的绑定。NetMsmqBinding
- 此绑定使用 MSMQ 进行传输,并支持断开连接的排队调用。
托管
- 它在网络上公开服务,以便客户端可以使用它。
- WCF 服务可以通过以下方式进行托管
- IIS 托管
- 自托管
- 控制台应用程序
- Windows 服务
- Windows 窗体或 WPF 应用程序
- WAS 托管
- 宿主应用程序的角色
- 启动和停止服务
- 侦听来自客户端的请求
- 将这些请求定向到服务
- 将响应发送回客户端
ServiceHost
对象在运行时与 WCF 服务关联。
绑定配置
- 绑定配置允许调整客户端和服务之间的通信特性。
- 设置传输的特性。
- 通常在客户端和服务两端都设置。
- 在端点本身上设置。
- 潜在设置
- 会话可靠性
- 消息大小
- 超时
- 安全
a) 可靠性
- 可与
NetTCPBinding
或WSHttpBinding
一起使用 - 启用通信重试
- 还强制消息排序
<reliableSession enabled="true" order="true"/>
b) 消息大小
- 可与任何绑定一起使用
- 增加或减少消息总大小,默认 64K
- 返回列表或流时很有用
<binding name="binding1" maxReceivedMessageSize="100000">
</binding>
c) 传输超时
- 可与任何绑定一起使用
- 设置 WCF 等待消息传输的最长时间
- 超过时抛出异常
- 默认值为 45
<binding name="binding1" sendTimeOut="00:01:00"
</binding>
最佳实践
- 始终将可靠性设置为
true
- 从重试中受益
- 排序可能仅对单向调用很重要
- 默认超时通常没问题
服务行为
- 属性控制服务的运行时方面
- 特性仅指定给服务
- 不影响绑定(传输)
- 通常对客户端是未知的
- 可以通过多种方式进行配置
- 两种类型的设置(不总是两者都有)
- 配置
- 属性装饰(在服务类级别)
- 服务行为在服务级别定义,而不是像绑定配置那样在端点级别定义。
配置
<service name="MyService" behaviourConfiguration="behaviour1">
<endpoint> </endpoint>
</service>
<behaviours>
<serviceBehaviors>
<behaviour name="behaviour1">
<.. ...>
</behavior>
</serviceBehaviors>
</behaviours>
属性装饰
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
Public class MyService : IMyService
{
... implementation code here....
}
服务调试
- 默认情况下,服务不将错误详情传递给客户端。
- 我们可以设置配置文件中的属性或服务上的属性以获取更清晰的错误信息。
- 在配置文件中
<behaviours> <serviceBehaviors> <behaviour name="behaviour1"> <serviceDebug includeExceptionDetailsInFault="true"/> </behavior> </serviceBehaviors> </behaviours>
- 在
Service
类中[ServiceBehavior(includeExceptionDetailsInFault=true)] Public class MyService : IMyService { ... implementation code here.... }
感谢阅读。如果您喜欢这篇文章,请投票。编码愉快!!!