WCF
WCF:一种专门用来构建分布式系统(指两个可执行程序需要交互数据)的API,通过使用WCF我们就可以使用大量的技术来将服务公开给调用者。
WCF基本构成
1.WCF服务程序集:向外部用户公开整体功能的类和接口(包含了许多WCF契约和他们的实现)
2.WCF服务宿主:承载WCF服务程序集的实体(可以是任何.net可执行程序,如控制台 winform wpf等)
3.WCF客户端:通过中间代理访问服务的应用程序(可以是任何.net可执行程序)
WCF中的ABC
1.地址(Address):服务的位置,可以硬编码到程序集中(System.Uri类型)或分离到.config文件中
2.绑定(Binding):WCF附带了许多绑定,每一个都针对特定的需要
——基于HTTP的绑定(数据以XML格式编码):
a.BasicHttpBinding :用来构建符合WS-Bssic Profile的WCF服务,使用HTTP作为传输,使用Text/XML作为默认的消息编码
b.WSHttpBinding:和 BasicHttpBinding 相似,但提供了更多WEB服务特性
c.WSDualHttpBinding:和WSHttpBinding 相似,用于双向契约
——基于TCP的绑定(数据以二进制格式编码):
a.NetNamedPipeBinding:用于相同机器.net应用程序之间的安全通信
b.NetPeerTcpBingding:提供了P2P网络应用程序的安全的绑定
c.NetTcpBingding:适合.net应用程序跨机器通信的安全的优化的绑定
——基于MSMQ的绑定
3.契约(Contract):WCF服务对外接口的定义和声明
创建一个WCF实例
1.构建WCF服务
//添加此特性以便使接口成为服务
[ServiceContract]
interface IService
{
//WCF方法须使用此特性来修饰
[OperationContract]
string Result(string str);
}public class Service : IService //实际上构建WCF服务也并不一定使用接口,可以将[ServiceContract] [OperationContract]直接应用到服务类上
{
public Service()
{
Console.WriteLine("the service await your input...");
}
public string Result(string str)
{
return "Hello " + str;
}
}
---------------------------不使用接口构建WCF服务如下----------------------------
[ServiceContract]
public class ServieTypeContract
{
[OperationContract]
void SomeMethed(){}
}
---------------------------------------------------------------------------------
2.承载WCF服务(最好是由Windows服务或IIS虚拟目录承载,此处使用控制台做宿主)
基本步骤:
a.在宿主的配置文件中,定义所承载的WCF服务的终结点(endpoint)
——MEX(元数据交换,一个WCF服务行为)默认是关闭的,会通过HTTP GET拦截任何元数据请求,如果希望允许VS来自动创建必要的客户端代理.config文件就必须启用MEX
<system.serviceModel>
<services> //包含了从宿主公开的WCF服务的集合<service name="WCF_Test.Service" behaviorConfiguration="WcfTestServiceBehavior"> //通过behaviorConfiguration关联服务和行为
<endpoint address="" //为空 则从<baseAddresses>中获取地址,也可为绝对地址或设置相对地址
binding="basicHttpBinding"
contract="WCF_Test.IService"/><endpoint address="mex" <!-- 启用MEX第一步 -->
binding="mexHttpBinding"
contract="IMetadataExchange"/>
<!-- 在专门的地方列出所有的根地址 -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:8899/WcfTestService"/> //由基地址http://localhost:8899 + 可选的URI组成
</baseAddresses>
</host></service>
</services><behaviors> <!-- 行为允许我们进一步限定宿主服务或客户端的功能 -->
<serviceBehaviors>
<behavior name="WcfTestServiceBehavior">
<serviceMetadata httpGetEnabled="true"/> <!-- 启用MEX第二步-->
</behavior>
</serviceBehaviors>
</behaviors></system.serviceModel>
b.通过编程使用ServiceHost类去提供终结点所提供的类型
static void Main(string[] args)
{
Console.WriteLine("**** WCF Host****");
//创建ServiceHost实例并通知它宿主时哪个WCF服务
using (ServiceHost serviceHost=new ServiceHost(typeof(Service)))
{
serviceHost.Open();
Console.WriteLine("the service is ready.....");
Console.WriteLine("Press the enter key to stop it.");
Console.ReadLine();
}Console.ReadLine();
}
c.确保宿主保持运行状态,以处理所收到的客户端的请求
在浏览器中输入http://localhost:8899/WcfTestService 便可看到服务的相关细节
3.构建客户端应用程序
a.新建一个控制台应用程序
b.确保宿主运行状态,添加服务引用,输入http://localhost:8899/WcfTestService,引用服务后客户端.config文件自动是配置好的如下
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8899/WcfTestService" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
name="BasicHttpBinding_IService" />
</client>
</system.serviceModel>
c.客户端编码如下
static void Main(string[] args)
{
Console.WriteLine("***** The client *****\n");
using (ServiceReference1.ServiceClient client=new ServiceReference1.ServiceClient())
{
Console.WriteLine("please input a name...");
string name = Console.ReadLine();
string result = client.Result(name);
Console.WriteLine("The Service Say : {0}",result);
}
Console.ReadLine();
}
d.运行应用程序得到类似如下的结果
The Service Say : Hello rock(你输入的名字)
多重绑定公开单独的WCF服务(使用简化配置配置.config文件, .net 4.5之后出现的新特性)
<system.serviceModel>
<services>
<service name="WCF_Test.Service" >
<!-- 使用默认绑定可以删除所有的endpoint元素和MEX指定的数据 -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:8899/WcfTestService"/>
<add baseAddress="net.tcp://localhost:8088"/> <!-- 添加额外的TCP绑定-->
</baseAddresses>
</host>
</service>
</services>
<!-- 添加bingding元素 不要配置name值 这样就会使用默认的配置 -->
<bindings>
<basicHttpBinding>
<binding />
</basicHttpBinding>
<netTcpBinding>
<binding closeTimeout="00:00:15"/> <!-- 可以指定一些binding属性 不指定将使用默认属性-->
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior> <!-- serviceMetadata元素不要设置name的值,这样就可以在运行时得到默认的MEX支持 -->
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors></system.serviceModel>
---------------------------关于MEX行为配置 -----------------------
代理生成工具必须在运行时发现服务,才能开始工作.在WCF中,可以通过启用MEX来允许这种运行时发现
而且多数宿主配置文件都需要启用MEX,因为我们很少修改MEX配置,所以最快捷的方式就是使用默认MEX配置
------------------------------------------------------------------
---------------------- .net4.5以后为甚么可以使用默认配置 --------------------------
因为.NET4.5有一个默认的machine.config文件,该文件指出了未指定WCF绑定时将使用的默认绑定
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding"/>
<add scheme="net.tcp" binding="netTcpBinding"/>
<add scheme="net.pipe" binding="netNamedPipeBinding"/>
<add scheme="net.msmq" binding="netMsmqBinding"/>
</protocolMapping>
</system.serviceModel>
-------------------------------------------------------------------------------------