阅读987 返回首页    go 阿里云 go 技术社区[云栖]


WCF后续之旅(15): 逻辑地址和物理地址

在默认的情况下,终结点的逻辑地址和物理地址是同一个URI。换句话说,终结的逻辑地址是必须的,如何物理地址没有指定的,默认使用逻辑地址作为物理地址。对于消息接收方的终结点来讲,物理地址就是监听地址,通过ServiceEndpoint的ListenUri表示:

   1: //---------------------------------------------------------------
   2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
   3: //---------------------------------------------------------------
   4: public class ServiceEndpoint
   5: {
   6:     ... ...
   7:     public Uri ListenUri { get; set; }
   8: } 

在对服务进行寄宿的时候,我们可以调用SeriviceHostBase或者ServiceHost的AddServiceEndpoint对应的重载来为添加的终结点指定ListenUri

   1: //---------------------------------------------------------------
   2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
   3: //---------------------------------------------------------------
   4: public abstract class ServiceHostBase : CommunicationObject, IExtensibleObject<ServiceHostBase>, IDisposable
   5: {
   6:     //... ...
   7:     public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, string address, Uri listenUri);
   8:     public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, Uri address, Uri listenUri);
   9: } 
  10:  
  11: public class ServiceHost : ServiceHostBase
  12: {
  13:     //... ...
  14:     public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address, Uri listenUri);
  15:     public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address, Uri listenUri);
  16: } 
  17:  

在下面的代码片断中,就为终结点指定了一个同于逻辑地址的物理地址(ListenUri):

   1: //---------------------------------------------------------------
   2: // ListenUri.cs (c) by 2008 Jiang Jin Nan
   3: //---------------------------------------------------------------
   4: using (ServiceHost serviceHost = new ServiceHost(typeof(CalculateService)))
   5: {
   6:    serviceHost.AddServiceEndpoint(typeof(ICalculate),new WSHttpBinding(),
   7:        "https://127.0.0.1:9999/calculateservice",
   8:        new Uri ("https://127.0.0.1:8888/calculateservice"));
   9:    Console.Read();
  10: } 
  11:  

   1: <configuration>
   2:     <system.serviceModel>        
   3:         <services>
   4:             <service name="Artech.WcfServices.Services.CalculateService">
   5:                 <endpoint  binding="wsHttpBinding"
   6:                     contract="Artech.WcfServices.Contracts.ICalculate"   address="https://127.0.0.1:8888/calculateservice"
   7:                     listenUri="https://127.0.0.1:8888/calculateservice" />
   8:             </service>
   9:         </services>
  10:     </system.serviceModel>
  11: </configuration> 
  12:  

   1: //---------------------------------------------------------------
   2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
   3: //---------------------------------------------------------------
   4: public class ClientViaBehavior : IEndpointBehavior
   5: {
   6:     //... ...
   7:     public Uri Uri { get; set; }
   8: } 

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <behaviors>
   5:             <endpointBehaviors>
   6:                 <behavior name="clientViaBehavior">
   7:                     <clientVia viaUri="https://127.0.0.1:8888/calculateservice" />
   8:                 </behavior>
   9:             </endpointBehaviors>
  10:         </behaviors>
  11:         <client>
  12:             <endpoint address="https://127.0.0.1:9999/calculateservice" behaviorConfiguration="clientViaBehavior"
  13:                 binding="wsHttpBinding" bindingConfiguration="" contract="Artech.WcfServices.Contracts.ICalculate"
  14:                 name="calculateservice">               
  15:             </endpoint>
  16:         </client>
  17:     </system.serviceModel>
  18: </configuration>

和ListenUriMode

   1: //---------------------------------------------------------------
   2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
   3: //---------------------------------------------------------------
   4: public enum ListenUriMode
   5: {
   6:     Explicit,
   7:     Unique
   8: } 

  • 如果采用TCP作为传输协议,同时采用端口共享情况下,会添加一个GUID作为后缀以确保地址的唯一性
  • 对于非TCP作为传输协议,会添加一个GUID作为后缀以确保地址的唯一性

   1: //---------------------------------------------------------------
   2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
   3: //---------------------------------------------------------------
   4: public class ServiceEndpoint
   5: {
   6:     //... ...
   7:     public Uri ListenUri { get; set; }
   8:     public ListenUriMode ListenUriMode { get; set; }
   9: } 
  10:  

   1: //---------------------------------------------------------------
   2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
   3: //---------------------------------------------------------------
   4: using (ServiceHost serviceHost = new ServiceHost(typeof(CalculateService)))
   5: {    
   6:  
   7:     ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(typeof(ICalculate), new WSHttpBinding(),
   8:     http://127.0.0.1:9999/calculateservice,    new Uri("https://127.0.0.1:8888/calculateservice"));
   9:     endpoint.ListenUriMode = ListenUriMode.Unique;
  10:     Console.Read();
  11: } 
  12:  

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3: <system.serviceModel>
   4:         <services>
   5:             <service name="Artech.ListenUriDemos.Services.CalculateService">
   6:                 <endpoint address="https://127.0.0.1:9999/calculateservice"  binding="wsHttpBinding" contract="Artech.ListenUriDemos.Contracts.ICalculate"
   7: listenUriMode="Unique" listenUri="https://127.0.0.1:8888/calculateservice" />
   8:             </service>
   9:         </services>
  10:     </system.serviceModel>
  11: </configuration> 
  12:  

image

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <bindings>
   5:             <netTcpBinding>
   6:                 <binding name="PortSharingBinding" portSharingEnabled="true" />
   7:             </netTcpBinding>
   8:         </bindings>
   9:         <services>
  10:             <service name="Artech.ListenUriDemos.Services.CalculateService">
  11:                <!--1. BasicHttpBinding & ListenUriMode.Explicit-->
  12:                 <endpoint address="https://127.0.0.1:5555/service1" binding="basicHttpBinding"
  13:                     name="httpExplicitListenUriMode" contract="Artech.ListenUriDemos.Contracts.ICalculate" />
  14:                 <!--2. BasicHttpBinding & ListenUriMode.Unique-->
  15:                 <endpoint address="https://127.0.0.1:6666/service2" binding="basicHttpBinding"
  16:                     name="httpUniquListenUriMode" contract="Artech.ListenUriDemos.Contracts.ICalculate"
  17:                     listenUriMode="Unique" />
  18:                <!--3. NetTcpBinding & ListenUriMode.Explicit-->
  19:                 <endpoint address="net.tcp://127.0.0.1:7777/service3" binding="netTcpBinding"
  20:                     bindingConfiguration="" name="tcpExplicitListenUriMode" contract="Artech.ListenUriDemos.Contracts.ICalculate" />
  21:                 <!--4. NetTcpBinding & ListenUriMode.Unique-->
  22:                 <endpoint address="net.tcp://127.0.0.1:8888/service4" binding="netTcpBinding"
  23:                     bindingConfiguration="" name="tcpUniquListenUriMode" contract="Artech.ListenUriDemos.Contracts.ICalculate"
  24:                     listenUriMode="Unique" />
  25:                 <!--5. NetTcpBinding & ListenUriMode.Unique & Port Sharing-->
  26:                 <endpoint address="net.tcp://127.0.0.1:9999/service5" binding="netTcpBinding"
  27:                     bindingConfiguration="PortSharingBinding" name="tcpPortSharingUniquListenUriMode"
  28:                     contract="Artech.ListenUriDemos.Contracts.ICalculate" listenUriMode="Unique" />
  29:             </service>
  30:         </services>
  31:     </system.serviceModel>    
  32: </configuration> 
  33:  

   1: //---------------------------------------------------------------
   2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
   3: //---------------------------------------------------------------
   4: using System;
   5: using System.ServiceModel;
   6: using Artech.ListenUriDemos.Services;
   7: using System.ServiceModel.Dispatcher; 
   8:  
   9: namespace Artech.ListenUriDemos.Hosting
  10: {
  11:     class Program
  12:     {
  13:         static void Main(string[] args)
  14:         {
  15:             using (ServiceHost serviceHost = new ServiceHost(typeof(CalculateService)))
  16:             {
  17:                 serviceHost.Open(); 
  18:  
  19:                 int i = 0;
  20:                 foreach (ChannelDispatcher channelDispatcher in serviceHost.ChannelDispatchers)
  21:                 {
  22:                     Console.WriteLine("第{0}个终结点的监听地址为: {1}", ++i,channelDispatcher.Listener.Uri);
  23:                 } 
  24:  
  25:                 Console.Read();
  26:             }
  27:         }
  28:     }
  29: } 
  30:  

   1: 第1个终结点的监听地址为: https://127.0.0.1:5555/service1
   2: 第2个终结点的监听地址为: https://127.0.0.1:6666/service2/d9ce6f30-3103-4ec9-b73b-34f32c65b0a1
   3: 第3个终结点的监听地址为: net.tcp://127.0.0.1:7777/service3
   4: 第4个终结点的监听地址为: net.tcp://127.0.0.1:1119/service4
   5: 第5个终结点的监听地址为: net.tcp://127.0.0.1:9999/service5/b4f69288-913b-43ec-8e42-e58f150ee91c

 

WCF后续之旅: 
WCF后续之旅(1): WCF是如何通过Binding进行通信的 
WCF后续之旅(2): 如何对Channel Layer进行扩展——创建自定义Channel 
WCF后续之旅(3): WCF Service Mode Layer 的中枢—Dispatcher 
WCF后续之旅(4):WCF Extension Point 概览 
WCF后续之旅(5): 通过WCF Extension实现Localization 
WCF后续之旅(6): 通过WCF Extension实现Context信息的传递 
WCF后续之旅(7):通过WCF Extension实现和Enterprise Library Unity Container的集成 
WCF后续之旅(8):通过WCF Extension 实现与MS Enterprise Library Policy Injection Application Block 的集成 
WCF后续之旅(9):通过WCF的双向通信实现Session管理[Part I] 
WCF后续之旅(9): 通过WCF双向通信实现Session管理[Part II] 
WCF后续之旅(10): 通过WCF Extension实现以对象池的方式创建Service Instance 
WCF后续之旅(11): 关于并发、回调的线程关联性(Thread Affinity) 
WCF后续之旅(12): 线程关联性(Thread Affinity)对WCF并发访问的影响 
WCF后续之旅(13): 创建一个简单的WCF SOAP Message拦截、转发工具[上篇] 
WCF后续之旅(13):创建一个简单的SOAP Message拦截、转发工具[下篇] 
WCF后续之旅(14):TCP端口共享 
WCF后续之旅(15): 逻辑地址和物理地址 
WCF后续之旅(16): 消息是如何分发到Endpoint的--消息筛选(Message Filter) 
WCF后续之旅(17):通过tcpTracer进行消息的路由



作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及着作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文链接

最后更新:2017-10-30 16:34:26

  上一篇:go  三步教你搭建给黑白照片上色的神经网络 !(附代码)
  下一篇:go  WCF后续之旅(17):通过tcpTracer进行消息的路由