WCF基础知识
管理方式配置终结点
地址格式:[基地址]/[可选的URI]
基地址格式:[传输协议]://[机器名或域名][:可选端口]
以管理方式配置一个终节点需要将终结点信息放到托管进程的配置文件中。如下面的服务定义:
namespace Mynamespace
{
[ServiceContract]
interface IMyContract
{。。。}
class MyService: IMyContract
{。。。}
}
管理方式配置终结点
<system.serviceModel>
<services>
<service name="MyNamespace.MyServices">
<endpoint
address="http://localhost:8000/MyService"
binging="wsHttpBinging"
Contract="MyNamespace.IMyContract"
/>
</service>
</services>
</system.serviceModel>
相同服务的多个终结点
<system.serviceModel>
<endpoint
address="http://localhost:8000/MyService"
binging="wsHttpBinging"
contract="IMyContract"
/>
<endpoint
address="net.tcp://localhost:8001/MyService"
binging="netTcpBinging"
contract="IMyContract"
/>
<endpoint
address="net.tcp://localhost:8001/MyService"
binging="netTcpBinging"
contract="IMyOtherContract"
/>
</system.serviceModel>
配置绑定
使用配置文件可以为终结点使用的绑定进行定制。添加bindingConfiguration属性。它的值要与<bindings>配置节点中定制的绑定名一致。
服务端绑定的配置
<system.serviceModel>
<services>
<service name="MyService">
<endpoint
address="net.tcp://localhost:8000/MyService"
bindingConfiguration="TransactionalTCP"
binding="netTcpBinding"
contract="IMyContract"
/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="TransactionalTCP"
transactionFlow="true"
/>
</netTcpBinding>
</bindings>
</system.serviceModel>
编程方式配置终结点
ServiceHost host = new ServiceHost(typeof(MyService));
Binding wsBinding = new WSHttpBinding();
Binding tcpBinding = new NetTcpBinding();
host.AddServiceEndpoint(typeof(IMyContract), wsBinding, "http://localhost:8000/MyService");
host.AddServiceEndpoint(typeof(IMyContract), tcpBinding, "net.tcp://localhost:8000/MyService");
host.Open();
address参数为string类型,contract参数为Type类型,binding参数为Binding抽象类的一个子类。
由宿主提供了基地址,只使用基地址
Uri tcpBaseAddress = new Uri("net.tcp://localhost:8000/");
ServiceHost host = new ServiceHost(typeof(MyService), tcpBaseAddress);
Binding tcpBinding = new NetTcpBinding();
//使用基地址作为地址
host.AddServiceEndpoint(typeof(IMyContract), tcpBinding, "");
//添加相对地址
host.AddServiceEndpoint(typeof(IMyContract), tcpBinding, "MyService");
//忽略基地址
host.AddServiceEndpoint(typeof(IMyContract), tcpBinding, "net.tcp://localhost:8000/MyService");
host.Open();
绑定配置
编程方式设置绑定属性。下面启用事务传播
ServiceHost host = new ServiceHost(typeof(MyService), tcpBaseAddress);
NetTcpBinding tcpBinding = new NetTcpBinding();
tcpBinding.TransactionFlow = true;
host.AddServiceEndpoint(typeof(IMyContract), tcpBinding, "net.tcp://localhost:8000/MyService");
host.Open();
元数据交换
服务有两种方案发布元数据:一种基于HTTP-GET协议;一种使用专门的终结点。
WCF能够为服务提供基于HTTP-GET的元数据,要显式的添加服务行为(Behavior)功能。
1管理方式启用元数据交换
配置文件急用元数据交换行为
<system.serviceModel>
<services>
<service name="MyService" behaviorConfiguration="MEXGET">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/"/>
</baseAddresses>
</host>
</service>
<service name="MyOtherService" behaviorConfiguration="MEXGET">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MEXGET">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
2编程方式启用元数据交换
启用元数据交换行为
ServiceHost host = new ServiceHost(typeof(MyService));
ServiceMetadataBehavior behavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (behavior == null)
{
behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior);
}
host.Open();
元数据交换终结点
HTTP-GET发布元数据仅是WCF一特性,并不保证交互的其他平台会支持。发布标准方式,通过称之为元数据交换终结点(MEX)发布。
三个MEX终结点,分别基于HTTP、TCP和IPC。第一个使用绝对地址,后两个使用相对地址。
<system.serviceModel>
<services>
<service name="MyService" behaviorConfiguration="MEX">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8001/"/>
<add baseAddress="net.pipe://localhost/"/>
</baseAddresses>
</host>
<endpoint
address="MEX"
binding="mexTcpBinding"
contract="IMetadataExchang"
/>
<endpoint
address="MEX"
binding="mexNamePipeBinding"
contract="IMetadataExchang"
/>
<endpoint
address="http://localhost:8000/MEX"
binding="mexHttpBinding"
contract="IMetadataExchang"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MEX">
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
编程方式添加MEX终结点
BindingElement bindingElement = new TcpTransportBindingElement();
CustomBinding binding = new CustomBinding(bindingElement);
Uri tcpBaseAddress = new Uri("net.tcp://localhost:9000/");
ServiceHost host = new ServiceHost(typeof(MyService), tcpBaseAddress);
ServiceMetadataBehavior behavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (behavior == null)
{
behavior = new ServiceMetadataBehavior();
host.Description.Behaviors.Add(behavior);
}
host.AddServiceEndpoint(typeof(IMetadataExchange), binding, "MEX");
host.Open();
客户端编程
管理方式配置客户端
客户端需要知道服务的位置与服务相同的绑定还要导入服务的七月定义。配置文件如下:
<system.serviceModel>
<client>
<endpoint name="MyEndpoint"
address="http://localhost:8000/MyService"
binding="wsHttpBiding"
contract="IMyContract"
/>
</client>
</system.serviceModel>
绑定配置
<system.serviceModel>
<client>
<endpoint name="FirstEndpoint"
address="net.tcp://localhost:8000/MyService"
behaviorConfiguration="TransactionTCP"
binding="netTcpBiding"
contract="IMyContract"
/>
</client>
<bindings>
<netTcpBinding>
<binding name="TransactionTCP"
transactionFlow="true"
/>
</netTcpBinding>
</bindings>
</system.serviceModel>
调用超时
<system.serviceModel>
<client>
<endpoint name="FirstEndpoint"
. . . .
behaviorConfiguration="LongTimeout"
binding="wsHttpBinding"
. . . .
/>
</client>
<bindings>
<wsHttpBinding>
<binding name="LongTimeout" sendTimeout="00:05:00" />
</wsHttpBinding>
</bindings>
</system.serviceModel>
Address是什么?
一个要和服务端通讯癿客户端要做癿第一件事情,就是搞清数据要収给谁?目癿地在哪?而Address正是通过一个Uri 来唯一标示一个WCF 癿终节点(EndPoint)癿,它标示了消息収送癿目癿地。在WCF 数据通讯中,它解决了服务在哪里癿问题。
如何在配置文件中指定 Address?
在配置文件中,有两种方弅可以挃定 Address,一种是绝对地址方弅,另外是相对地址方弅,凾删如下:
绝对地址
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/" />
</baseAddresses>
</host>
<endpoint address ="http://localhost:8731/Service" binding="basicHttpBindi
ng" contract="Wcf_Address_Config.IService1"> </endpoint>
相对地址
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/" />
</baseAddresses>
</host>
<endpoint address ="Service1" binding="basicHttpBinding" contract="Wcf_A
ddress_Config.IService1"></endpoint>
配置文件规范
多个服务的配置文件
<system.serviceModel>
<services>
<service name="WCFService.WCFServicePerCall" behaviorConfiguration="WCFService.WCFServiceBehavior">
<endpoint
address="net.tcp://localhost:9001/WCFServicePerCall"
binding="netTcpBinding"
contract="WCFService.IWCFService">
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9001/"/>
</baseAddresses>
</host>
</service>
<service name="WCFService.WCFServicePerSession" behaviorConfiguration="WCFService.WCFServiceBehavior">
<endpoint
address="net.tcp://localhost:9002/WCFServicePerSession"
binding="netTcpBinding"
contract="WCFService.IWCFService">
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9002/"/>
</baseAddresses>
</host>
</service>
<service name="WCFService.WCFServiceSingleTon" behaviorConfiguration="WCFService.WCFServiceBehavior">
<endpoint
address="net.tcp://localhost:9003/WCFServiceSingleTon"
binding="netTcpBinding"
contract="WCFService.IWCFService">
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9003/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFService.WCFServiceBehavior">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>