WCF是MS基于SOA(Service Oriented Architecture)推出的.net平台下的框架产品。WCF是使用托管代码建立和运行面向服务应用程序的统一框架。它使得开发者能够建立一个跨平台的安全,可信赖,事务性的解决方案,且能与已有系统兼容协作。WCF是MS分布式应用程序开发的集大成者,它整合了.Net平台下所有的和分布式系统有关的技术。
WCF的优势:
1.统一性
WCF是一些技术的整合,WCF是完全由托管代码编写,因此开发WCF的应用程序与开发其它的.Net应用程序没有太大的区别。
2.互操作性
WCF最基本的通信机制是SOAP,这就保证了系统之间的互操作性,即使是运行不同的上下文中。这种通信可以是基于.net到.net间的通信.可以跨进程,跨机器甚至于跨平台的通信,只要支持标准的WebService.应用程序可以运行在windows操作系统下。
3.安全与可信赖
在Soap的header中增加了WS-ReliableMessaging允许可信赖的端对端通信。
4.兼容性
安装WCF并不会影响原有的技术(ASMX,Remoting)
WCF Service由一个Endpoints集合组成,每个Endpoint就是用于通信的入口,客户端和服务端通过Endpoint交换信息。
Address是Endpoint的网络地址,它标记了消息发送的目的地。
Binding描述的是如何发送消息。(如:消息发送的传输协议TCP,HTTP)
Contract描述的是消息所包含的内容,以及消息的组织和操作方式。(one-way,duplex,request/reply)
Endpoint中的ABCs分别代表的含义是:where,how,what.
当WCF发送消息时,通过address知道消息的发送的地址,通过binding知道怎样来发送它,通过contract知道发送的消息是什么。
在WCF中,类ServiceEndpoint代表一个Endpoint,在类中包含的EndpointAddress,binding,ContractDescription类型分别对应Endpoint的Address,Binding,Contract.
EndPointAddress类又包含URI,Idnentity,可选的headers集合组成
Endpoint安全的唯一性识别通常是通过其URI的值
(但为了避免一些特殊情况造成URI的重复,又引入了Identity附加到URI上,保证了Endpoint地址的唯一性)
至于可选的AddressHeader则提供了一些附加的信息,尤其是当多个Endpoint在使用同样的URI地址信息时,AddressHeader就是非常必要了。
Binding类包含Name,Namespace,BindingElement集合
Binding的Name以及Namespace是服务元数据的唯一标识。
BindingElement是WCF通信时binding的方式。
如:
SecurityBindingElement:Endpoint使用SOAP消息安全方式。
ReliableSessionBindingElement:Endpoint利用可信赖消息确保消息的传送。
TcpTransportBindingElement:Endpoint利用TCP作为通信的传输协议。
ContractDescription用于描述WCF的Contracts以及它们的操作operations.
在ContractDescription类中,每个Contract的operation都有相对应的OperationDescription,用于描述operation的类型。
在OperationDescription中还包含了MessageDecription集合用于描述Message.
在WCF编程模型中,ContractDescription通常是在定义Contract的接口或类中创建。
对于这个接口或类类型,标记以ServiceContractAttribute,而其Operation方法则标记以OperationContractAttribute.
*当然我们也可以不利用CLR的Attribute,而采用手工创建。
Contract中还包含了ContractBehavior的集合,ContractBehavior类型可以用于修改或扩展Contract的行为。
关系图如下:
ContractDescription
---Name
---NameSpace
---OperationDescription
----MessageDescription
---IContractBehavior
其实WCF专门提供了行为Behavior,它可以对客户端和服务端的一些功能进行修改或扩展。
还有Security behavior用于控制安全与授权
transaction behavior控制事务
由于WCF需要管理的是服务端与客户端的通信。
服务端:WCF提供了类ServiceDescription用于描述一个WCFservice
客户端:WCF管理的是发送消息时需要使用到的通信Channel,类ChannelDescription描述了这样的客户端通道。
ServiceDescription
----Service Type
----IServiceBehavior
----ServiceEndpoint
----EndpointAddress
----Binding
----ContractDescription
我们可以利用代码的方式Create ServiceDescription object, or using WCF's Attribute, or using tool--SvcUtil.exe.
下面我们来一个Hello World,来结束WCF的第一节。
using System.ServiceModel;
//标记了[ServiceContract],这就使得类成为了一个WCF Service
[ServiceContract]
public class HelloWorld
{
//标记了[OperationContract],而成为该Service的一个Operation
[OperationContract]
public void Hello()
{
Console.WriteLine("Hello World!");
}
}
不过WCF推荐的做法是将接口定义为一个Service,这使得WCF Service更灵活了。
毕竟对于一个接口而言,可以在同时有多个类实现这个接口,这也意味着可以有多个ServiceContract的实现。
以上面代码可以修改为:
[ServiceContract]
public interface IHello
{
[OperationContract]
void Hello();
}
而类HelloWorld则实现这个IHello interface:
public class HelloWorld:IHello
{
public void Hello()
{
Console.WriteLine("Hello World!");
}
}
最后一个WCFService必须有host作为它运行的环境。
那么Host可以是Asp.net,Windows service,普通的应用程序。
下面是Host的代码:
using System.ServiceModel
public class HostApp
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(HelloWorld),new Uri(http://localhost:8080/HelloService));
host.AddServiceEndpoint(typeof(IHello),new BasicHttpBinding(),"Svc");
host.Open();
Console.WriteLine("Start Your Service.");
Console.ReadKey();
host.Close();
}
}
以上我们创建了一个ServiceHost对象,通过它就可以创建WCF Runtime,WCF Runtime是一组负责接收和发送消息的对象。
ServiceHost可以创建SerivceDescription对象,利用ServiceDescription,ServiceHost为每一个ServiceEndPoint创建一个EndpointListener.
ServiceHost
--- ServiceDescription
--- EndpointListener
*在创建ServiceHost时,传递的type类型参数,不能是interface.
所以,我在这里传入的是typeof(HelloWorld).
AddServiceEndpoint()方法实现了为Host添加Endpoint的功能.
其参数正好是Endpoint的三部分(Address,Binding,Contract),
此时IHello,为ServiceContract,其方法Hello为OperationContract
Open()方法用于创建和打开Service运行时;
Close()方法来关闭这个运行时。(当然实际上此方法是可以不调用的,因为应用程序结束后,系统会自动Close Host的.)
但是,大家都需要养成好的习惯,WCF仍然要求显式调用Close()方法。
因为Service运行时其本质是利用Channel来完成消息的传递,When open service runtime, using a Channel in System,invoke back, we need release using for channel. so maybe use "using" to manage resource of the ServiceHost release.
嗯,定义好一个WCF Service,并将其运行在host上后,如何实现它与客户端的通信呢?
请见下篇:)