终结点的地址的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. iOS 限制输入字数完美解决方案

    关于限制输入字数以前也做过,网上也很多方法.但都不够完美,本方法可防止中文联想.粘贴等突破长途限制.可防止Emoji截为两半导致编码出问题.   - (void)textFieldDidChange: ...

  2. 【Algorithm】选择排序

    一. 算法描述 选择排序:比如在一个长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......第N-1 ...

  3. 【C语言】练习2-9

     题目来源:<The C programming language>中的习题P38  练习2-9:  在求对二的补码时,表达式x &= (x-1)可以删除x中最右边值为1的一个二进 ...

  4. mongodb及mongoclient在win7下的编译和使用

    1.导言 折腾mongodb几个小时最终有结果了.呃.如今就简单总结一下. 事实上我的需求非常easy,就是在C++代码中调用mongodb的库函数.也就是要得到mongoclient.lib.本来想 ...

  5. 删除vector指定位置的元素

    原文链接: http://www.cnblogs.com/yeahgis/archive/2012/05/29/2523476.html #include <vector>#include ...

  6. PMD-Java 代码检查工具对 error 和 warning 的配置

    PMD是一款优秀的Java程序代码检查工具.该它可以检查Java代码中是否含有未使用的变量.是否含有空的抓取块.是否含有不必要的对象等. 但在使用过程中,你会项目中发现存在大量的 PMD 插件报出的 ...

  7. CommonView for wifi抓包破解WPA无线网络

    运行环境:win8 64位+intel 5100n网卡 步骤1:下载CommonView完全破解版,非破解版只有跑10分钟 http://www.nlver.cn/soft/7305.html 步骤2 ...

  8. Four Node.js Gotchas that Operations Teams Should Know about

    There is no doubt that Node.js is one of the fastest growing platforms today. It can be found at sta ...

  9. 在 Windows Server 2008 中部署带 SignalR 的网站出错

    一直是在 Windows Server 2008 R2 或更高版本的 Windows 中进行部署,没有遇到过此现象,不知道是不是因为系统的原因. 现象为从浏览器访问配置 signalr 的地址返回 4 ...

  10. ios总结2018

      1.为什么说Objective-C是一门动态的语言? 1.object-c类的类型和数据变量的类型都是在运行是确定的,而不是在编译时确定.例如:多态特性,我们可以使用父类指针来指向子类对象,并且可 ...