一、URI(统一资源标识)
  web服务可视为一种网络资源,并且可以通过一个URI来进行唯一标识。而服务通过终结点的形式发布出来,我们所说的一个服务在大部分场景中实际上指的是服务的某个终结点。终结点的核心就是一个URI,它可以作为终结点的唯一标识,还具有路由或寻址的功能。地址对应的URI不仅代表了服务所在位置,也代表了消息路由的目标地址
  URI结构:
    [传输协议(Scheme)]://[主机名称|域名|IP地址]:[可选端口]/[资源路径]
  例如:
    http://artech.com:9999/myservices/calculatorservice.svc

二、HTTP/HTTPS
  HTTP全称为 HyperText Transfer Protocol(超文本传输协议),是建立在TCP/IP簇上的应用层协议。由于其简单、易用的特性,已经成为事实上的Internet标准。
    1、TTTP提供简单的请求-回复消息传输方式
    2、HTTP是无状态的,每次请求都是互相独立的
    3、HTTP是无连接的,基于HTTP的数据传输无须事先打开连接

  HTTPS全称为HypeText Transfer Protoco over Secure Socket Layer(安全超文本传输协议),它采用了SSL(Secure Socket Layer) 的HTTP。而SSL是一个进行数据加密的协议,很多安全性要求高的网站都采用HTTPS。WCF通过HTTPS实现了基于HTTP的传输安全(Transport Security)

  注意:HTTP和HTTPS的URI分别使用http和https作为传输协议前缀,默认使用的端口号分别为80和443
  http://artech.com/myservices/calculatorservice.svc = http://artech.com:80/myservices/calculatorservice.svc

三、Net.TCP
  TCP全称为Transport Control Protocol(传输控制协议),在整个TCP/IP簇上处于核心地位。从整个协议分层结构来看,位于应用层之下,网络层(IP协议)之上。
    1、TCP是基于连接的传输协议,在开始进行数据传输之前,通过客户端和服务端之间的3次“握手”创建连接;在结束传输之后,通过4此“握手”终止连接
    2、TCP是有状态的,由于数据传输在一个确定的连接中进行,因此可以保持每次数据传输的状态
    3、TCP支持全双工通信,一旦连接成功创建,数据就可以在两个方向上同时传输
    4、TCP支持可靠通信,IP协议本身提供的数据是不可靠的,数据的可靠传输只能通过TCP来保证

  注意:WCF通过NetTcpBinding支持基于TCP的传输。对于TCP的URI,其传输协议前缀为net.tcp://。默认端口号为808

四、Net.Pipe
  命名管道(Named Pipes)是Windows平台及UNIX系统下实现跨进程通信(Inter Process Communication,IPC)的标准实现方式。虽然命名管道本身可以实现跨机器的通讯,但是WCF只将命名管道专门用于同一台机器的跨进程的通讯,所以基于命名管道的URI的主机名称|域名|IP地址部分只能是本机的机器名、localhost、127.0.0.1,基于命名管道的URI以net.pipe为前缀,而在基于同一台机器的不同进程间通信中,端口没有任何意义

五、Net.Msmq
  消息队列(Message Queuing,也称MSMQ),是微软对消息服务领域的开创性尝试。由于消息队列采用了特殊的通信机制,因此对于改善和提高系统的可扩展性和高可用性具有重要的意义。
  按照可访问行划分如下:
    1、公共消息队列:公有队列的名称被注册到AD域中,所以我们无须指定队列所在的机器名称就可以访问队列。当将某个公有队列从一台机器转移到另一台机器时,访问该队列的应用可以保持不变。公有队列还可以提供基于域账号的Windows认证机制,所以对于正式发布的应用来说,通常采用公有队列
    2、私有消息队列:因为公有队列需要注册到AD域中所以它只能用于域(Domain)模式下。在工作组(Work Group)模式下,只能使用私有队列。而访问私有队列需要指定包含队列所在机器名称的路径

注意:WCF下基于消息队列的URI具有net.msmq前缀。在主机名称和队列名称通过字符Private标识私有队列,而对于公有队列的URI,表示队列类型部分则不是必需的
net.msmq://artech.com/myservices(公有队列)
net.msmq://artech.com/Private/myservices(私有队列)

六、EndpointAddress

  终结点在WCF应用编程接口中通过System.ServiceModel.Description.ServiceEndpoint类型表示,ServiceEndpoint核心属性如下:

public class ServiceEndpoint
{
public EndpointAddress Address { get; set; } //地址
public Binding Binding { get; set; } //绑定
public ContractDescription Contract { get; set; } //契约
}

  表示终结点地址的Address属性是一个类型为System.ServiceModel.EndpointAddress的对象(地址核心功能:服务标识/定位、辅助寻址和服务身份标识)

public class EndpointAddress
{
public AddressHeaderCollection Headers { get; }//辅助寻址(地址包头列表存放一些寻址信息)
public Uri Uri { get; }               //服务与定位(可以是物理地址,也可以是逻辑地址)
public EndpointIdentity Identity { get; }    //身份标识(服务身份,被客户端用于认证服务)
}

  EndpointIdentity:客户端终结点通过地址的该属性表示自己希望调用服务的真实身份。调用前,服务端将自己的凭证(Windows凭证、X.509证书凭证等)提供给客户端,而客户端通过以EndpointIdentity对象代表的服务身份与凭证进行比较,来验证正在调用的服务确实是自己所希望调用的服务

七、服务端终结点地址

  WCF通过ServiceHost完成宿主的寄宿,而被寄宿的服务通过添加到ServiceHost的终结点暴露出来成为可被调用寻址和调用的资源

public class ServiceHost : ServiceHostBase
{
public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address);
public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address, Uri listenUri);
public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address);
public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address, Uri listenUri);
}

  ServiceHostBase是ServiceHost的基类

public abstract class ServiceHostBase : CommunicationObject, IExtensibleObject<ServiceHostBase>, IDisposable
{
   public virtual void AddServiceEndpoint(ServiceEndpoint endpoint);
public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, string address);
public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, string address, Uri listenUri);
public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, Uri address);
public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, Uri address, Uri listenUri);
}

    implementedContract:表示服务契约类型全名的字符串

    listenUri:服务的监听地址

using (ServiceHost host = new ServiceHost(typeof(Service.CalculatorService)))
{
//添加终结点(一个基于WSHttpBinding绑定的终结点 终结点地址:http://127.0.0.1:3721/calculatorservice 服务契约的类型:ICalculator)
host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:3721/calculatorservice");
host.AddServiceEndpoint(typeof(ICalculator), new NetTcpBinding(), "http://127.0.0.1:3721/calculatorservice");
}

  添加的终结点我们可以通过他的只读属性Description获取

public abstract class ServiceHostBase : CommunicationObject, IExtensibleObject<ServiceHostBase>, IDisposable
{
public ServiceDescription Description { get; }
}

  ServiceDescription:表示整个服务的描述(终结点列表)

public class ServiceDescription
{
public string Name { get; set; }
public string Namespace { get; set; }
public KeyedByTypeCollection<IServiceBehavior> Behaviors { get; }
public string ConfigurationName { get; set; }
public ServiceEndpointCollection Endpoints { get; }
public Type ServiceType { get; set; }
public static ServiceDescription GetService(Type serviceType);
public static ServiceDescription GetService(object serviceImplementation);
}

  除了使用代码添加终结点还可以使用配置文件方式配置终结点

<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="calculatorservice/metadata" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="metadataBehavior" name="Service.CalculatorService">
<endpoint address="calculatorservice" binding="wsHttpBinding"
bindingConfiguration="" name="Service.CalculatorService" contract="Service.Interface.ICalculator" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:9999" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>

  这样我们就不需要再使用代码来添加终结点了

using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
{
host.Opened += delegate
{
Console.WriteLine("CalculatorService 启动,按任意键终止服务!");
};
host.Open();//开启服务
Console.Read();
}

  注意:WCF在进行基地址和相对地址匹配的时候,会根据终结点的绑定类型从基地址列表中获取与传输协议相匹配的基地址

  地址终结点共享:一般情况下,服务实现一个单一的契约接口,所以服务的所有终结点共享相同的契约。既然这些终结点具有相同的契约,他们的地址就不可能相同。但是对于一个实现了多个服务契约接口的服务来说,多个基于不同契约的终结点就可以共享相同的地址,但是必须共享相同的绑定对象实例(这个地方有待完善,没有验证。。。)

  例如我们有两个契约接口 ICalculator1和ICalculator2 服务契约的实现类 CalculatorService

using (ServiceHost host = new ServiceHost(typeof(Service.CalculatorService)))
{
 WSHttpBinding binding = new WSHttpBinding();
//添加终结点(一个基于WSHttpBinding绑定的终结点 终结点地址:http://127.0.0.1:3721/calculatorservice 服务契约的类型:ICalculator)
host.AddServiceEndpoint(typeof(ICalculator1), binding , "http://127.0.0.1:3721/calculatorservice");
host.AddServiceEndpoint(typeof(ICalculator2), binding , "http://127.0.0.1:3721/calculatorservice");
}

  

  

2.WCF学习--地址的更多相关文章

  1. WCF学习之旅—WCF服务部署到应用程序(十)

    上接  WCF学习之旅—WCF寄宿前的准备(八) WCF学习之旅—WCF服务部署到IIS7.5(九) 五.控制台应用程序宿主 (1) 在解决方案下新建控制台输出项目 ConsoleHosting.如下 ...

  2. WCF学习之旅—WCF服务的WAS寄宿(十二)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) 八.WAS宿主 IIS ...

  3. WCF学习之旅—TcpTrace工具(二十六)

    止文(WCF学习之旅—TcpTrace工具(二十五))介绍了关于TcpTrance的一种使用方式,接下来介绍第二种使用方式. 三.通过ListenUri实现基于tcpTracer的消息路由 对于路由的 ...

  4. WCF学习之旅—TcpTrace工具(二十五)

    前面的几篇文章,我们学习了怎么开发WCF应用程序与服务,也学习了如何进行WCF的配置.对于Web Service与WCF服务应用,服务端与客户端的通信是通过收发SOAP Message进行,我们如何有 ...

  5. WCF学习之旅—实现支持REST客户端应用(二十四)

    WCF学习之旅—实现REST服务(二十二) WCF学习之旅—实现支持REST服务端应用(二十三) 在上二篇文章中简单介绍了一下RestFul与WCF支持RestFul所提供的方法,及创建一个支持RES ...

  6. WCF学习之旅—TCP双工模式(二十一)

    WCF学习之旅—请求与答复模式和单向模式(十九) WCF学习之旅—HTTP双工模式(二十) 五.TCP双工模式 上一篇文章中我们学习了HTTP的双工模式,我们今天就学习一下TCP的双工模式. 在一个基 ...

  7. WCF学习之旅—HTTP双工模式(二十)

    WCF学习之旅—请求与答复模式和单向模式(十九) 四.HTTP双工模式 双工模式建立在上文所实现的两种模式的基础之上,实现客户端与服务端相互调用:前面介绍的两种方法只是在客户端调用服务端的方法,然后服 ...

  8. WCF学习之旅—WCF第二个示例(七)

    三.创建客户端应用程序 若要创建客户端应用程序,你将另外添加一个项目,添加对该项目的服务引用,配置数据源,并创建一个用户界面以显示服务中的数据. 在第一个步骤中,你将 Windows 窗体项目添加到解 ...

  9. WCF学习之旅——第一个WCF示例(三)

    第五步:创建客户端 WCF应用服务被成功寄宿后,WCF服务应用便开始了服务调用请求的监听工作.此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据.接下来我们来创建客户端 ...

随机推荐

  1. C# 高性能 TCP 服务的多种实现方式Cowboy.Sockets

      本篇文章的主旨是使用 .NET/C# 实现 TCP 高性能服务的不同方式,包括但不限于如下内容: APM 方式,即 Asynchronous Programming Model TAP 方式,即 ...

  2. php 中 http_build_query用法

    http_build_query (PHP 5) http_build_query -- 生成 url-encoded 之后的请求字符串描述string http_build_query ( arra ...

  3. Mac下用命令行压缩和解压rar文件的方法

    废话不多说,直接进入主题 第一步:下载RAR工具包,根据自己需要下载相对应的版本 第二步:解压对应的压在的压缩包rarosx-5.4.0.tar.gz(我下载的是5.4.0版本) 第三步:从终端进入到 ...

  4. 关于web开发中路径的问题的总结

    web开发中的一个困扰web开发新人的是路径问题: 1:项目的静态资源的根路径:http://localhost:8080/sqec-monitor 即是部署在web服务器中(比如tomcat)中项目 ...

  5. centos7安装MongoDB4.0(yum安装)

    1.添加 yum repo vi /etc/yum.repos.d/mongodb-org-4.0.repo 添加如下内容 [mongodb-org-4.0] name=MongoDB Reposit ...

  6. 004-URL编码转换函数:escape()、encodeURI()、encodeURIComponent()

    一.概述 函数出现时间:                     escape()                                javascript 1.0             ...

  7. Linux_Bash脚本基础

    目录 目录 Bash使用基础 if 语句 运算符 逻辑表达式 不将执行指令的结果显示出来 echo 语句 从Bash接受输入参数 Case语句 循环 for 语句 While语句 内置变量和函数 AW ...

  8. vue.jsc初体验

    Vue 1.安装脚手架 (1)npm install -g vue-cli (2)Vue -v //查看是否安装成功 (3)Vue init webpack name(名称) (4)Npm insta ...

  9. Git使用gitignore建立项目过滤规则

    在进行协作开发代码管理的过程中,常常会遇到某些临时文件.配置文件.或者生成文件等,这些文件由于不同的开发端会不一样,如果使用git add . 将所有文件纳入git库中,那么会出现频繁的改动和push ...

  10. 聊聊redis的监控工具

    序 本文主要研究一下redis的监控工具 redis-stat redis-stat是一个比较有名的redis指标可视化的监控工具,采用ruby开发,基于redis的info命令来统计,不影响redi ...