服务是一组公开功能的集合。
服务内部包含了如语言、技术、版本与框架等概念,服务之间的交互只允许使用规定的通信模式
外界客户端并不知道服务内部的实现细节,所以WCF服务通常通过元数据的方式描述可用的功能及服务可能采用的通信方式
WCF不允许客户端直接与服务交互,客户端总是使用代理将调用转发给服务 ,WCF允许客户端跨越执行边界与服务通信,如跨应用程序域、进程甚至网络。
WCF要求客户端对本地对象还是远程对象都保持一致的编程模型,而不用考虑服务的位置
WCF对本地对象还是远程对象都使用代理调用服务,大大简化了应用程序的编程模型,使用代理可以拦截WCF的请求,增加WCF的价值
在WCF中,每个服务都有一个唯一的地址(Address)。
地址包含两个重要的元素:服务位置及传输协议。
服务位置包含目标机器名、站点、通信端口、管道?(或队列),以及一个可选的特定路径或URI。
WCF的所有服务都会公开为契约(Contract)
契约与平台无关,是描述服务功能的标注方式
绑定是开发人员控制WCF程序与其他消息交互的主要手段。从功能上看,绑定创建了通道工厂惑通道侦听器的堆栈对象。绑定直接惑间接创建的对象是WCF实现各种消息功能(例如,传输、安全性、事务性)的主要方式。一个绑定封装了诸如传输协议、消息编码、通信模式、可靠性、安全性、事务传播,以及互操作性等相关选项,使得它们保持一致。
WCF标准绑定
每个WCF服务都必须托管在Windows进程中,该进程称为宿主进程(host process)
单个宿主进程可以托管多个服务,相同的服务类型也可以托管在多个宿主进程中
class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"><%@ ServiceHost Language="C#" Debug="true" Service="ch01.Service1" CodeBehind="Service1.svc.cs"Factory="MyServiceFactory" %>
<serviceActivations> <add relativeAddress ="MyService.svc" service="MyService" factory="MyServiceFactory"/> </serviceActivations>
class NyServiceFactory:ServiceHostFactory { protected override ServiceHost CreateServiceHost(Type serviceType,Uri[] baseAddress) { ServiceHost host = new ServiceHost(serviceType,baseAddress); //自定义步骤 return host; } }
七、终结点
服务与地址、绑定和契约有关。
地址定义了服务的位置,绑定定义了服务的通信方式,契约则定义了服务的内容。称为”服务的ABC“。
WCF用终结点表示这样一组关系。终结点是地址、绑定和契约的一种混合品。
每一个终结点都包含这三个元素,而宿主则负责公开终结点。
每个服务至少公开一个业务终结点,每个终结点有且只有一个服务契约。
以管理方式配置终结点需要将终结点信息放到托管进程的配置文件中,例如下面给出的服务定义:
namespace MyNamespace { [ServiceContract] interface IMyContract {....} class MyContract:IMyContract {....} }下面演示了配置文件要求的配置入口:
<system.serviceModel> <services> <service name="MyNamespace.MyService"> <endpoint address="http://localhost:8000/MyService" binding="wsHttpBinding" contract="MyNamespace.IMyContract" /> </service> </services> </system.serviceModel>当指定服务和契约类型时,必须使用类型全名
<system.serviceModel> <services> <service name="MyNamespace.MyService"> <host> <baseAddress> <add baseAddress="http://localhost:8000/"/> </baseAddress> </host> <endpoint address="MyService" binding="wsHttpBinding" contract="MyNamespace.IMyContract" /> </service> </services> </system.serviceModel>
如果宿主没有提供匹配的基地址,则在装载服务时会抛出异常。配置终结点地址时,可以为基地址添加相对URI.
使用配置文件可以设置终结点使用的绑定。因此,需要在endpoint节上添加bindingConfguration属性。下面演示了启用事务传播的方法:
<system.serviceModel> <services> <service name="MyNamespace.MyService"> <endpoint address="net.tcp://localhost:8000/MyService" bindingConfiguration="TransactionalTCP" binding="wsHttpBinding" contract="MyNamespace.IMyContract" /> </service> </services> <bindings> <netTcpBinding> <biinding name="TransactionalTCP" transactionFlow="true"/> </netTcpBinding> </bindings> </system.serviceModel>
WCF允许使用默认绑定。默认绑定会影响使用此配置文件的应用程序的所有服务。默认绑定不需要使用名称。如下:
<netTcpBinding>
<biinding transactionFlow="true"/>
</netTcpBinding>
默认绑定会作用在所有没有显式配置的终结点上。如下:
<system.serviceModel> <services> <service name="MyNamespace.MyService"> <endpoint address="net.tcp://localhost:8000/MyService" binding="wsHttpBinding" contract="MyNamespace.IMyContract" /> </service> </services> <bindings> <netTcpBinding> <biinding transactionFlow="true"/> </netTcpBinding> </bindings> </system.serviceModel>
每个绑定类型最多有一个默认绑定。
以编程方式配置终结点是通过编程调用将终结点添加到ServiceHost实例中。ServiceHost定义了多个重载版本的AddServiceEndpoint()方法。
ServiceHost host = new ServiceHost(typeof (MyService)); BasicHttpBinding bind = new BasicHttpBinding(); host.AddServiceEndpoint(typeof (IMyervice), bind,"http://localhost:8000/MyService"); host.Open();
Uri httpBaseAddress = new Uri("http://localhost:8000/");
ServiceHost host = new ServiceHost(typeof (MyService),httpBaseAddress);
BasicHttpBinding bind = new BasicHttpBinding();
//使用基地址
host.AddServiceEndpoint(typeof(IMyervice) , bind , "");
//使用相对地址
host.AddServiceEndpoint(typeof (IMyervice), bind, "MyService");
//忽略基地址
host.AddServiceEndpoint(typeof(IMyervice) , bind , "http://localhost:8000/MyService");
host.Open();
ServiceHost host = new ServiceHost(typeof (MyService));
NetTcpBinding tcp = new NetTcpBinding();
tcp.TransactionFlow = true;
host.AddServiceEndpoint(typeof(IMyervice) , tcp , "net.tcp://localhost:8000/MyService");
host.Open();
如果服务宿主没定义终结点,只提供了一个基地址,则WCF将会为服务添加默认的终结点,即默认终结点。
WCF会为每个基地址、每个契约添加终结点,使用基地址作为服务地址。
WCF会根据基地址的scheme来推断绑定类型。对于HTTP,WCF使用basic绑定。
默认绑定会影响默认终结点,WCF也会通过连接绑定和契约来命名终结点。
也可以使用ServiceHost的AddDefaultEndpoints()方法明确添加默认终结点。
对于默认终结点,WCF会使用基地址的scheme来推测绑定类型。这个推测过程成为协议映射。
加入是TCP、IPC和MSMQ,则只有一个映射选择。但是,对于HTTP(或HTTPS),WCF默认使用basic绑定,则要在配置文件里使用protoclMapping节点来设置:
<protocolMapping> <add binding="basicHttpsBinding" scheme="https" /> </protocolMapping>
也可以指定专门的绑定方式:<protocolMapping> <add binding="basicHttpsBinding" scheme="https" bindingConfiguration="..." /> </protocolMapping>
必须在配置文件里定义协议映射。
参考资料:《WCF服务编程》