要发布Metadata,ServiceHost必须有一个http的baseAddress,所以在构造ServiceHost实例时,就需要在构造方法中加入这个http的baseAddress,这个http的baseAddress就是对外发布的Metadata地址。
1.5. 打开ServiceHost,开始提供服务
ServiceHost构建好了,添加了需要的Endpoint、behavior后,使用ServiceHost.Open()方法开发ServiceHost实例,开始对外提供服务。
2、 客户端
2.1. 引用service
客户端要访问服务端的服务,首先要知道服务端的服务提供了什么方法,就是要知道服务的Contract.如何取得服务端的Contract有几种方法
2.1.1. 直接把服务端的Contract的副本拷贝到客户端
这个方法是最原始的一种方法,这样保证了服务端跟客户端使用同一份Contract.但是,这个方法不值得提倡,因为双方的Contract是同一个来源,但是毕竟是两个独立的物理存在,它们之间只能人为的来保证其一致性。
2.1.2. 使用Svcutil.exe工具获得服务端Contract并生成本地服务代理类
大家知道,web service是通过WSDL对外提供服务的描述,以便客户端能够通过wsdl知道这个web service所包含的方法、方法的签名等等信息,客户端通过wsdl就能知道怎么去调用这个web service.
到了WCF时代,微软依然采用WSDL来提供对WCF服务的描述。
前面服务端给ServiceHost添加了一个ServiceMetadataBehavior类型的Behavior,目的就是让服务端对外提供WSDL形式的服务Metadata描述。
微软提供了Svcutil.exe工具用来通过WSDL生成客户端Contract和代理功能:
Svcutil.exe httpbaseAddress
httpbaseAddress 就是服务端设置的http的baseAddress.当然前提是服务端在ServiceHost. Behaviors添加一个ServiceMetadataBehavior类型的Behavior,并设置HttpGetEnabled属性为true,允许对外暴露服务端Metadata描述
运行Svcutil.exe后,生成两个文件,一个是WCF配置文件,一个是包含了服务端Contract和对应于服务端service的本地代理类的cs文件。
生成的cs文件有下面的规律:
l 引用服务端的服务所涉及的Contract(Interface类型)基本都原样引用到客户端(可能会自动给Contract添加一些Attribute)。
l 服务端的Endpoint到了客户端,每个具有不同Contract的Endpoint都会在客户端生成一个代理类。Contract相同,binding不同的Endpoint使用同一个客户端代理类。
2.1.3. 在客户端项目中添加Service reference
在vs2005中安装了WCF的extention后,在项目的References上点击右键,会多出来一个“Add Service Reference”的选项,这就是用来引用WCF服务的,引用地址就是服务端设置的http的baseAddress.
在这里引用WCF服务,跟使用Svcutil.exe命令一样,会在项目中生成同样的两个文件。
2.2. 生成客户端service代理实例
引用服务后,客户端生成了配置文件和包含了Contract和本地代理类的cs文件,这里我们完全不使用配置文件,所以把生成的配置文件从项目中排除。
2.2.1. 使用ChannelFactory Generic
使用ChannelFactory Generic类的CreateChannel静态方法CreateChannel,返回一个客户端代理。
static TChannel CreateChannel(Binding binding, EndpointAddress endpointAddress);
localhost.IService proxy = ChannelFactory.CreateChannel(new BasicHttpBinding(), new EndpointAddress(":8080/WCFService/Service"));
这个方法包含了一个Endpoint的ABC三个主要元素:
Address – new EndpointAddress(":8080/WCFService/Service")是地址。
Bingding – new BasicHttpBinding() 是绑定。
Contract —— localhost. IService是引用服务后