终结点的地址的Uri属性作为终结点地址的唯一标示。

包括客户端终结点服务端终结点。

一、服务端终结点:

服务端的终结点通过宿主的添加方法暴露出来,从而成为可以调用的资源。

下面是将服务绑定到宿主的代码:

定义宿主时使用的是契约的实现类,也即服务类添加终结点到宿主的使用的是契约接口

1.1代码实现

代码实现往指定服务的宿主上添加终结点:

1.2配置实现

下面通过配置实现:

代码实现对应的配置如下:

1.3svc文件的配置

下面也给出svc文件中的配置:

由于svc文件被部署到了IIS上,所以对应的有端口,本身svc是一个文件,对应的也有路径,所以配置不用使用address字段

1.4获取宿主上的终结点

可以向一个宿主身上添加多个服务终结点,所以一个服务可以有多个终结点。每一个服务对应着一个宿主。当然可以获取所有的终结点。

宿主有个关于服务的描述属性,该属性包括了宿主的承载的所有服务终结点

1.5使用基地址+相对地址类添加契约终结点

当终结点比较多时,并且前面的部分相同时,可以通过基地址+相对地址类来添加终结点到宿主上面。

宿主这时也会根据使用的Binding类型的不同来区分请求的终结点。注意上面的一个是NetTcpBinding,一个是BasicHttpBinding。这就要求同一种绑定类型的基地址只能有一种,要不然会弄乱的。

下面是配置方式

IIS来讲文件所在地点就是基地址:

1.6当一个服务同时实现了两个契约时,需要共享相同的地址,那么必须保证其绑定是同一个。方法是new一个绑定供两个终结点使用。

二、客户端终结点

客户端通过引用服务,最终生成了一个代理类:客户端服务代理类继承自ClientBase<TChannel>和TChannel,其中TChannel是和服务端等效的接口,不过名称是自动生成的,我们可以使用此代理类来操作数据;也可以通过ChannelFactory<TChannel>来创建代理类来操作数据。

下面看简单的看一下代理类的基类的部分构造方法和两个属性。下面的属性有个ChannelFactory<TChannel>,其实第一种方法的代理是通过ClientBase<TChannel>的属性创建的。
public abstract class ClientBase<TChannel>

{
        protected ClientBase();
        protected ClientBase(ServiceEndpoint endpoint);
        protected ClientBase(string endpointConfigurationName);
        protected ClientBase(Binding binding, EndpointAddress remoteAddress);
        protected ClientBase(string endpointConfigurationName, EndpointAddress remoteAddress);
        protected ClientBase(string endpointConfigurationName, string remoteAddress);

protected TChannel Channel { get; }
        public ChannelFactory<TChannel> ChannelFactory { get; }
}

为什么客户端能调用服务端的方法类操作数据?

由构造函数来看主要是通过使用终结点来和服务端相对应,来让客户端能够找到服务端的对象。

下面给出客户端的终结点的第一种配置:

<system.serviceModel>
    <client>
      <endpoint name="myEndPoint"
                address="http://127.0.0.1/wcfservices/"
                binding="wsHttpBinding"
                contract="ServiceReference1.ICalculator">
      </endpoint>
    </client>
</system.serviceModel>
如果是使用上面的配置,那么就可以使用基类参数为endpointConfigurationName=myEndPoint的构造方法构造。

三、地址报头

每个终结点都含有一个Headers属性,客户端来说会被添加到请求消息的报头集合中,对于服务端来说,会提取响应的报头信息和本地终结点的地址报头来进行比较以选择出于请求消息相匹配的终结点。

地址报头的创建

AddressHeader CreateAddressHeader(string name, string ns, object value, XmlObjectSerializer serializer);

以下是服务端终结点的形状:

下面是如何使用地址报头的代码:

using (ChannelFactory<CalculatorService> channelFactory = new ChannelFactory<CalculatorService>("wsHttpBinding"))
          {
              CalculatorService calculator = channelFactory.CreateChannel();
              Uri uri = new Uri("http://127.0.0.1:3721/calculatorservice");
              AddressHeader header = AddressHeader.CreateAddressHeader("Licensed User", "http://www.artech.com", "UserType");
                  using (OperationContextScope operationContextScope=new OperationContextScope(calculator as IContextChannel))
              {
                  OperationContext.Current.OutgoingMessageHeaders.Add(header.ToMessageHeader());
                  double result = calculator.Divide(1, 2);
              }

}

如果AddressFilterMode为Any,报头可以不匹配。使用如下:

[ServiceBehavior(AddressFilterMode=AddressFilterMode.Any]
  public class CalculatorService:ICalculator

四、逻辑地址和物理地址

物理地址对于服务端来说是监听地址,对于客户端来说是真正发送的目标地址。

针对SOAP的消息交换来说,服务的逻辑地址是<To>报头的地址。

对于服务端来说物理地址和逻辑地址分离的表现在:用于监听地址和收到的消息TO报头的地址不一致。

在客户端表现逻辑地址和物理地址分离的表现:<To>的报头地址和消息真正发送目标地址不一致。

需要中介服务参与消息路由的通信就涉及物理地址和逻辑地址的分离。

对于服务消费者来说,消息发送的逻辑地址是针对服务的最终提供者的。

<endpoint address="http://127.0.0.1:5555/service1"
                 binding="basicHttpBinding"
                 contract="Artech.WcfServices.Service.Interface.ICalculator" />
       <!--2. BasicHttpBinding + ListenUriMode.Unique-->
       <!--6666加GUID-->
       <endpoint address="http://127.0.0.1:6666/service2"
                 binding="basicHttpBinding"
                 contract="Artech.WcfServices.Service.Interface.ICalculator"
                 listenUriMode="Unique" />
       <!--3. NetTcpBinding & ListenUriMode.Explicit-->
       <!--7777-->
       <endpoint address="net.tcp://127.0.0.1:7777/service3"
                 binding="netTcpBinding"
             contract="Artech.WcfServices.Service.Interface.ICalculator"/>
       <!--4. NetTcpBinding & ListenUriMode.Unique-->
       <!--会使用未占用的端口-->
       <endpoint address="net.tcp://127.0.0.1:8888/service4"
                 binding="netTcpBinding"
                 contract="Artech.WcfServices.Service.Interface.ICalculator"
                 listenUriMode="Unique" />
       <!--5. NetTcpBinding & ListenUriMode.Unique & Port Sharing-->
       <!--会使用原来的端口,后面加个GUID-->
       <endpoint address="net.tcp://127.0.0.1:9999/service5"
                 binding="netTcpBinding"
                 bindingConfiguration="PortSharingBinding"
                 contract="Artech.WcfServices.Service.Interface.ICalculator"
                 listenUriMode="Unique" />

上面的配置主要说明了监听地址和监听方式决定了最终的监听地址。

using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
            {
                host.Open();
                int i = 0;
                foreach (ChannelDispatcher channelDispatcher in host.ChannelDispatchers)
                {
                    Console.WriteLine("{0}: {1}", ++i, channelDispatcher.Listener.Uri);
                }
                Console.ReadKey();
            }

提供服务的主机,对应着一个或者多个分发器,每个分发器对应着一个或多个监听器。

wcf提供了4中类型的行为:1.服务行为、2契约行为、3终结点行为、4操作行为。行为是客户端或者服务端本地实现某个功能的一种方式,是一种单边的行为。

2和4被定义为特性。3只能通过配置,1可以声明和配置。1.服务行为,主要用于service behaviorConfiguration="" 。3.终结点行为主要用于终结点的endpoint endpointConfiguration=""

服务和终结点的行为配置如下:

终结点行为配置还可以如下:

<behaviors>
      <endpointBehaviors>
        <behavior name="aa" >
          <clientVia viaUri="http://127.0.0.1:55551/service1"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>

上面的viaUri是代表的是物理地址,即消息真正发送的目的地址。

实现服务端逻辑地址和物理地址的分离的demo

客户端配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <ws2007HttpBinding>
        <binding name="myBinding">
          <security mode="None"/>
        </binding>
      </ws2007HttpBinding>
    </bindings>
    <client>
      <endpoint name="calculatorservice"
             address="http://127.0.0.1:9999/calculatorservice"
             binding="ws2007HttpBinding"
             bindingConfiguration="myBinding"
             contract="Artech.WcfServices.Service.Interface.ICalculator"/>
    </client>
  </system.serviceModel>
</configuration>

服务端配置:

<system.serviceModel>
  <bindings>
    <ws2007HttpBinding>
      <binding name="myBinding">
        <security mode="None"/>
      </binding>
    </ws2007HttpBinding>
  </bindings>
  <services>
    <service name="Artech.WcfServices.Service.CalculatorService">
      <endpoint address="http://127.0.0.1:9999/calculatorservice"
                binding="ws2007HttpBinding"
                bindingConfiguration="myBinding"
                contract="Artech.WcfServices.Service.Interface.ICalculator"
                listenUri="http://127.0.0.1:8888/CalculatorService"
                listenUriMode="Explicit"/>
    </service>
  </services>
</system.serviceModel>

路由转发设置:监听9999,目的8888.To包含的是9999.

接下来是客户端逻辑地址和物理地址的分离的实例:

服务端

<system.serviceModel>
  <bindings>
    <ws2007HttpBinding>
      <binding name="myBinding">
        <security mode="None"/>
      </binding>
    </ws2007HttpBinding>
  </bindings>
  <services>
    <service name="Artech.WcfServices.Service.CalculatorService">
      <endpoint address="http://127.0.0.1:9999/calculatorservice"
                binding="ws2007HttpBinding"
                bindingConfiguration="myBinding"
                contract="Artech.WcfServices.Service.Interface.ICalculator"/>
    </service>
  </services>
</system.serviceModel>

客户端地址

<system.serviceModel>
  <behaviors>
    <endpointBehaviors>
      <behavior name="clientVia">
        <clientVia viaUri="http://127.0.0.1:8888/calculatorservice"/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <ws2007HttpBinding>
      <binding name="myBinding">
        <security mode="None"/>
      </binding>
    </ws2007HttpBinding>
  </bindings>
  <client>
    <endpoint name="calculatorservice"
           address="http://127.0.0.1:9999/calculatorservice"
           binding="ws2007HttpBinding"
           bindingConfiguration="myBinding"
           behaviorConfiguration="clientVia"
           contract="Artech.WcfServices.Service.Interface.ICalculator"/>
  </client>
</system.serviceModel>

路由转发从8888转到9999,双方的Address必须相同,为了让<To>内的地址相同。可以知道发送到哪里。


信道分发器进行请求监听和消息接受,终结点分发器最终完成对消息的处理。

信道分发器相当于保安,当有人找公司里面的人时,保安会通知具体的公司人去处理事情。

WCF终结点——终结点地址(EndpointAddress)的更多相关文章

  1. 【WCF】终结点的监听地址

    终结点主要作用是向客户端公开一些信息入口,通过这个入口,可以找到要调用的服务操作.通常,终结点会使用三个要素来表述,我记得老蒋(网名:Artech,在园子里可以找到他)在他有关WCF的书里,把这三要素 ...

  2. 【WCF】自定义地址头的筛选器

    前面的文章中,老周已向大伙伴们介绍了如何在终结点上使用地址头,只要服务是沿着该终结点调用的,那么每一次调用都会自动把地址头插入到SOAP消息的Header列表中. 而通过前一篇文章中的示例,大家也看到 ...

  3. WCF: 没有终结点在侦听可以接受消息的 这通常是由于不正确的地址或者 SOAP 操作导致的。

    问题:     由于我这里的wcf服务是采用“BasicHttpBinding”的方式,即安全绑定模式,客户端在引用这个服务后所生成的终结点配置(endpoint )就变成了<endpoint ...

  4. [Solution] 一步一步WCF(2) 终结点Endpoint

    繁忙的一天又一天,不管其他,先继续WCF吧. Endpoint包含地址,绑定,契约三要素.WCF作为一个Windows平台下最大的通信框架.通过终结点承载了所有通信功能.所以终结点的作用将非常重要. ...

  5. WCF 配置终结点并调用服务

    wcf通过xml文件配置终结点什么的感觉有点小麻烦,个人还是觉得用代码形式配置比较好,当然在发布的时候可能会比较麻烦,需要重新编译... 下面将wcf service寄宿在控制台应用程序中并配置终结点 ...

  6. wcf 远程终结点已终止该序列 可靠会话出错

    https://social.msdn.microsoft.com/Forums/office/zh-CN/9f0c76d2-85b0-4cd3-979d-ceda7947bcd1/-?forum=w ...

  7. wcf客户端终结点样本集合

    1. <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IUser" /&g ...

  8. WCF *.svc 自定义地址路由映射

    一般在创建WCF服务时会用Serivce.svc文件访问,地址如:http://localhost/applicationname/Serivce.svc/Name 现在用路由映射成:http://l ...

  9. 【WCF】为终结点地址应用地址头

    记得不久前,老周写过博文,探讨过在ContextScope以一定的范内向发出的消息中插入消息头,scope只能为特定的某一次服务操作的调用而添加SOAP头,要是需要在每次调用操作协定的时候都插上Hea ...

随机推荐

  1. CentOS7.2安装python2.7.12

    目前CentOS7.2自带的python版本是python2.7.5.由于yum这个软件需要系统自带的python工作. 如果冒然用自己安装的python替换掉系统自带的,可能造成yum不工作. 先安 ...

  2. HTML CSS边框阴影的实现

    一款用CSS控制背景图像平铺,从而实现区域边框阴影的效果,虽然用到了图片,但可贵之处是本代码不管你需要阴影的区域是多大,它都能自动适应,因些还是很值得收藏一下的,兼容所有的IE浏览器. <!DO ...

  3. SQL SERVER 2008自动发送邮件(完整版)

    这两天都在搞这个东西,从开始的一点不懂,到现在自己可以独立的完成这个功能!在这个过程中,CSDN的好多牛人都给了我很大的帮助,在此表示十二分的感谢!写这篇文章,一是为了巩固一下,二嘛我也很希望我写的这 ...

  4. golang学习笔记---函数、方法和接口

    函数:对应操作序列,是程序的基本组成元素. 函数有具名和匿名之分:具名函数一般对应于包级的函数,是匿名函数的一种特例,当匿名函数引用了外部作用域中的变量时就成了闭包函数,闭包函数是函数式编程语言的核心 ...

  5. 简单易用的安装文件制作工具NSIS的使用demo示例

    安装文件制作工具NSIS 使用总结   在给客户开发客户端软件时,为避免技术人员亲自上门安装带来额外的成本损耗,通常我们都会自作一个安装包,以确保我们开发的程序的相关依赖资源.环境在客户端运行前能自动 ...

  6. C#基础第二天-作业-九九乘法表-打印星星

    一.打印九九乘法表图形为下列效果图中的三角型的一种例: 图一效果1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 ...

  7. MapReduce中,new Text()引发的写入HDFS的输出文件多一列的问题

    前段时间业务系统有个模块数据没有了,在排查问题的时候发现中间处理环节出错了,错误日志为文件格式不正确,将数据导出后发现这个处理逻辑的输入文件中每一行都多了一列,而且是一个空列(列分隔符是\t).第一次 ...

  8. groupby elasticsearch

    GET usertag/usertag/_search { "query": { "match": { "tagname": "春 ...

  9. shell - 常识

    一.用户登陆进入系统后的系统环境变量: $HOME 使用者自己的目录 $PATH 执行命令时所搜寻的目录 $TZ 时区 $MAILCHECK 每隔多少秒检查是否有新的信件 $PS1 在命令列时的提示号 ...

  10. spring boot下JedisCluster方式连接Redis集群的配置

    最近在使用springboot做项目,使用redis做缓存.在外网开发的时候redis服务器没有使用集群配置,所有就是用了RedisTemplate的方式进行连接redis服务器.但是项目代码挪到内网 ...