1、统一资源标识(URI)
URI唯一标识一个网络资源,也表示资源所在的位置以及访问的方式。
结构:[传输协议(scheme)]://[主机名称|域名|IP地址]:[可选端口]/[资源路径]
1)、HTTP/HTTPS:
HTTP:超文本传输协议,建立在TCP/IP族上的应用层协议。
特点:无状态,相互独立,无连接(无需事先打开连接)、简单的请求-回复协议。
HTTPS:安全超文本传输协议,是采用SSL的HTTP。
2)、Net.TCP:
TCP传输控制协议,位于应用层之下,网络层(IP协议)之上。
特点:基于连接的传输协议,有状态的(是否连接上),支持双工通信,支持可靠通信。
net.tcp://hanshuai.com/myservice
3)、Net.Pipe:
命名管道,window或Unix系统下实现跨进程的通信方式。
net.pipe://127.0.0.1/myservice
4)、Net.Msmq:
消息队列,按照可访问性分为公共消息队列和私有消息队列。
公共消息队列:队列名称被注册到AD域中,无需指定队列所在的机器名称就可以访问,可以提供基于域账号的windows认证机制。
私有消息队列:只能用在域(Domain)模式下,访问需要指定包含队列所在的机器名称的路径。
net.msmq://hanshuai.com/myservices
net.msma://hanshuai.com/private/myservices
2、EndpointAddress
ServiceEndpoint三个核心属性:地址、绑定、契约。
EndpointAddress包含三个成员:URI、Headers、Identity,都是只读属性。
1)、服务端终结点地址:
服务添加终结点的方式有两种,一种是通过ServiceHostBase或者其子类ServiceHost的AddServiceEndpoint方法添加,具体有很多种重载方式。另外一种是通过配置的方式添加:
配置:<configuration>
<system.serviceModel>
<services>
<service name ="service1">
<endpoint name="endpoint1" address="..." binding ="..." contract="..."/>
<endpoint name="endpoint2" address="..." binding ="..." contract="..."/>
.....
</service>
</services>
</system.serviceModel>
</configuration>
上面是服务端最基本的配置结构,IIS寄宿的方式,无需通过配置指定终结点的地址。
a、基地址与相对地址:
服务终结点地址可以通过“基地址+相对地址”的方式进行设置,如:
Uri[] baseAddresses=new Uri[2];
baseAddresses[0]=new Uri("http://127.0.0.1/myservices");
baseAddresses[1]= new Uri("net.tcp://127.0.0.1/myservices");
using(serviceHost host=new ServiceHost(typeof(MyTestService),baseAddresses)
{
host.AddServiceEndpoint(typeof(ITest),new BasicHttpBinding(),"MyTestService");
host.AddServiceEndpoint(typeof(ITest),new NetTcpBinding(),"MyTestService");
host.open();
}
注意:同一个Uri[]数组中,定义的基地址类型,不可以重复,例如不可以包含两个"http:"开头的地址,这样host寻址的时候就不知道找哪个 了。
这种方式同样可以通过配置的方式实现:
.......
<service ...>
<host>
<baseAddresses>
<add baseAddress="base address 1"/>
<add baseAddress="base address 2"/>
</baseAddresses>
<endpoint address ="relative address 1" .../>
<endpoint address ="relative address 2" .../>
</host>
.......
b、地址的跨终结点共享:
对于一个实现了多个契约借口的服务来说,多个基于不同契约的终结点就可以共享相同的地址。
<service name="myservice">
<endpoint address="http://127.0.0.1/myservice" binding="wsHttpBinding" contract="IContract1"/>
<endpoint address="http://127.0.0.1/myservice" binding="wsHttpBinding" contract="IContract2"/>
</service>
这种方式,用ServiceHost的AddServiceEndpoint方法添加配置定义的终结点的时候,绑定对象必须指定为同一个对象:
using(ServiceHost host=new ServiceHost(typeof(MyService))
{
WSHttpBinding binding=new WSHttpBiding();
host.AddServiceEndpoint(typeof(IContract1),binding);
host.AddServiceEndpoint(typeof(IContract2),binding);
host.open();
}
2)、客户端终结点地址:
客户端通过服务代理(Service Proxy)实现对服务的调用。客户端生成代码的核心类继承自ClientBase<TChannel>,TChannel泛型代表服务契约类型。
客户端和服务端的契约接口相同,例如生成的客户端类:public class TestClient:ClientBase<ITest>,ITest。服务调用的本质是采用匹配的客户端终结点对目标终结点进行调用的。
客户端的配置简单如下:
<client>
<endpoint name ="endpoint1" address =".." binding=".." contract ="..."/>
<endpoint name ="endpoint2" address =".." binding=".." contract ="..."/>
</client>
客户端和服务端终结点的配置一定要对应相同。
ChannelFactory<TChannel>的CreateChannel函数创建服务代理类。
3)、地址报头:
终结点地址EndpointAddress对象的Headers属性,是一个AddressHeaderCollection类型,这是个AddressHeader集合,我们称AddressHeader为地址报头。
<endpoint ...>
<headers>
<UserType xmlns="...">
licensed User
</UserType>
</headers>
</endpoint>
服务端的地址报头主要用于辅助实现对终结点的选择,客户端的终结点地址报头的最终目的是为了请求消息添加相应的报头,客户端可以手动的添加报头。
服务端的地址报头,可以对客户端进行授权,只有通过的许可的客户端才可以进行服务访问。(安全访问)
浙公网安备 33010602011771号