• WCF-ServiceEndpoint的监听地址与监听模式


      ServiceEndpoint具有一个可读可写的ListenUri属性,该属性表示服务端终结点的物理监听地址,该地址默认和终结点逻辑地址一致(即ServiceEndpoint的Uri)。对于客户端来说,请求真正发送的目标地址是服务的监听地址,默认情况下终结点的逻辑地址和监听地址是一样的。监听地址可以通过ServiceHost的AddServiceEndpoint指定。

    public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address);
    public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address);
    public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address, Uri listenUri);
    public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address, Uri listenUri);
    

     在实际的运行中,ServiceEndpoint的最终监听地址还要由ListenUriMode一起控制。ListenUriModel定义如下:

    public enum ListenUriMode
    {
      Explicit = 0,
      Unique = 1,
    }

      Explicit表示终结点的监听地址严格采用ListenUri指定设置的Uri,Unique会根据终结点采用的策略确定最终使用的监听地址。

    在采用Unique的情况下,监听器地址的生成策略如下:

      1.采用Tcp协议并且不采用端口共享,会选择一个未使用的端口作为保证监听地址的唯一性。

      2.采用Tcp协议并且采用端口共享,会在原有的监听地址后面加一个Guid以保证监听地址的唯一性。

      3.采用非Tcp协议,会在原有的监听地址后面加一个Guid以保证监听地址的唯一性。

    下面代码演示服务端是如何确定终结点的监听地址,监听地址在信道分发器(ChannelDispatcher)中体现,

    using System.ServiceModel;
    using System.ServiceModel.Description;
    using System.ServiceModel.Channels;
    namespace host
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(mywcf.Calculator)))
                {
                    ServiceEndpoint endpoint1 = host.AddServiceEndpoint(typeof(mywcf.ICalculator), new WSHttpBinding(), "http://localhost:1111");
    
                    ServiceEndpoint endpoint2 = host.AddServiceEndpoint(typeof(mywcf.ICalculator), new WSHttpBinding(), "http://localhost:2222");
                    endpoint2.ListenUriMode = ListenUriMode.Unique;
    
                    ServiceEndpoint endpoint3 = host.AddServiceEndpoint(typeof(mywcf.ICalculator), new NetTcpBinding(), "net.tcp://localhost:3333");
                    endpoint3.ListenUriMode = ListenUriMode.Unique;
    
                    NetTcpBinding tcpbind = new NetTcpBinding();
                    tcpbind.PortSharingEnabled = true;
                    ServiceEndpoint endpoint4 = host.AddServiceEndpoint(typeof(mywcf.ICalculator), tcpbind, "net.tcp://localhost:4444");
                    endpoint4.ListenUriMode = ListenUriMode.Unique;
    
                    ServiceEndpoint endpoint5 = host.AddServiceEndpoint(typeof(mywcf.ICalculator), new NetTcpBinding(), "net.tcp://localhost:5555");
                    host.Opened += delegate { Console.WriteLine("Service Start!"); };
                    host.Open();
    
                    foreach (var dispatch in host.ChannelDispatchers)
                    {
                        Console.WriteLine(dispatch.Listener.Uri);
                    }
                }
            }
        }
    }
    

     输出:

    endpoint1的监听地址采用默认值,与逻辑地址一致。endpoint2使用了Unique模式,并且是非tcp协议类型,在默认的前提下添加一个GUID。endpoint3使用了Unique模式,并且是tcp协议类型,运行是分配了一个没有被使用的端口。endpoint4采用了端口共享模式,并且是tcp协议类型,监听地址加一个GUID。endpoint5监听地址默认与逻辑地址一致。

    示例代码也可以用配置文件方式演示,配置文件如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.serviceModel>
        <bindings>
          <netTcpBinding>
            <binding portSharingEnabled="True" name="tcpbind"></binding>
          </netTcpBinding>
        </bindings>
        <services>
          <service name="mywcf.Calculator">
            <endpoint contract="mywcf.ICalculator" binding="wsHttpBinding" address="http://localhost:1111"></endpoint>
            <endpoint contract="mywcf.ICalculator" binding="wsHttpBinding" address="http://localhost:2222" listenUriMode="Unique"></endpoint>
            <endpoint contract="mywcf.ICalculator" binding="netTcpBinding" address="net.tcp://localhost:3333" ></endpoint>
            <endpoint contract="mywcf.ICalculator" binding="netTcpBinding" address="net.tcp://localhost:4444" listenUriMode="Unique"></endpoint>
            <endpoint contract="mywcf.ICalculator" binding="netTcpBinding" bindingConfiguration="tcpbind" address="net.tcp://localhost:5555" listenUriMode="Unique" ></endpoint>
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    

     采用了配置文件后服务端代码就很简单了,如下:

    using System.ServiceModel;
    namespace hostxml
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(mywcf.Calculator)))
                {
                    host.Opened += delegate { Console.WriteLine("Service Start!"); };
                    host.Open();
                    foreach (var dispatch in host.ChannelDispatchers)
                    {
                        Console.WriteLine(dispatch.Listener.Uri);
                    }
                }
            }
        }
    }
    
  • 相关阅读:
    成幻Online Judge 1.00 Beta 环境配置
    AJAX Control Toolkit tabs 的纯Javascript演示
    Microsoft ASP.NET Futures (July 2007)中History在客户端的使用(即不必安装ASP.NET Futures)
    HTML中利用纯Microsoft Ajax Library做出可调用WebSerives的AutoComplete
    初雪,小词一首
    vs 2008中使用Asp.net Ajax智能感知Intellisense
    IE6下Ms Ajax Lib 调用Ajaxtoolkit时Common_InvalidPaddingUnit未定义的解决方法
    由成幻OnlineJudge学习如何做自己的AcmIcpc在线评判系统-5.在线编译与测试系统代码粗解
    成幻Online Judge 1.00 源代码下载 [20070804]
    Asp.net中动态在中加入Scrpit标签
  • 原文地址:https://www.cnblogs.com/lh218/p/4379318.html
Copyright © 2020-2023  润新知