WCF技术剖析(卷1)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.3.2 逻辑地址和物理地址

在WCF中,每个终结点都包含两个不同的地址:逻辑地址和物理地址。逻辑地址就是以终结点Address属性表示的地址。至于物理地址,对于消息发送端来讲,就是消息被真正发送的目的地址;而对于消息的接收端来讲,就是监听器真正监听的地址。按照WS-Addressing的说法,逻辑地址和物理地址分别对应着地址To和Via。

服务端逻辑地址与物理地址

对于消息接收方的终结点来讲,物理地址就是监听地址,通过ServiceEndpoint的ListenUri表示。

        public class ServiceEndpoint
        {
            //其他成员
            public Uri ListenUri { get; set; }
        }

在对服务进行寄宿的时候,可以调用ServiceHostBase或ServiceHost的AddServiceEndpoint对应的重载来为添加的终结点指定ListenUri。在下面的代码中,为终结点指定了一个不同于逻辑地址的物理地址(ListenUri)。

        public abstract class ServiceHostBase : CommunicationObject,
        IExtensibleObject<ServiceHostBase>, IDisposable
        {
            //其他成员
            public ServiceEndpoint AddServiceEndpoint(string implementedContract,
              Binding binding, string address, Uri listenUri);
            public ServiceEndpoint AddServiceEndpoint(string implementedContract,
              Binding binding, Uri address, Uri listenUri);
        }
        public class ServiceHost : ServiceHostBase
        {
            //其他成员
            public ServiceEndpoint AddServiceEndpoint(Type implementedContract,
              Binding binding, string address, Uri listenUri);
            public ServiceEndpoint AddServiceEndpoint(Type implementedContract,
              Binding binding, Uri address, Uri listenUri);
        }
        using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
        {
            serviceHost.AddServiceEndpoint(typeof(ICalculator),new WSHttpBinding(),
              "http://127.0.0.1:9999/CalculatorService",
              new Uri ("http://127.0.0.1:8888/CalculatorService"));
            Console.Read();
        }

当然,ListenUri也可以通过配置进行指定,下面的配置和上面的代码是等效的。

        <configuration>
            <system.serviceModel>
                <services>
                  <service name="Artech.WcfServices.Services.CalculatorService">
                        <endpoint  binding="wsHttpBinding"
                            contract="Artech.WcfServices.Contracts.ICalculator"
                              address="http://127.0.0.1:8888/CalculatorService"
                            listenUri="http://127.0.0.1:8888/CalculatorService" />
                  </service>
                </services>
            </system.serviceModel>
        </configuration>

客户端逻辑地址与物理地址

前面已提到,对于消息的发送端来讲,物理地址其实就是消息发送的真正目的地址。该地址通过一个特殊的终结点行为(EndpointBehavior)来指定:ClientViaBehavior。ClientViaBehavior定义的URI代表该物理地址。

        public class ClientViaBehavior : IEndpointBehavior
        {
            //其他成员
            public Uri Uri { get; set; }
        }

同一般的终结点行为一样,ClientViaBehavior通过相应的配置应用到WCF客户端运行时。在下面的配置中,通过viaUri设置了一个不同于终结点地址(http://127.0.0.1:9999/CalculatorService)的物理地址:http://127.0.0.1:8888/CalculatorService

        <?xml version="1.0" encoding="utf-8" ?>
        <configuration>
            <system.serviceModel>
                <behaviors>
                  <endpointBehaviors>
                        <behavior name="clientViaBehavior">
                            <clientVia viaUri=
                              "http://127.0.0.1:8888/CalculatorService" />
                        </behavior>
                  </endpointBehaviors>
                </behaviors>
                <client>
                  <endpoint address="http://127.0.0.1:9999/CalculatorService"
                        behaviorConfiguration="clientViaBehavior"
                        binding="wsHttpBinding" bindingConfiguration=""
                          contract="Artech.WcfServices.Contracts.ICalculator"
                        name="CalculatorService">
                  </endpoint>
                </client>
            </system.serviceModel>
        </configuration>