WCF中的几种地址总结

  在WCF中有几种涉及到地址的概念:基地址与相对地址、逻辑地址与物理地址。本文就从

WebService寻址开始,总结一下WCF中的几种地址。

 

目录:
  1. WebService寻址 
  2. 逻辑地址与物理地址 
  3. 基地址、相对地址、绝对地址 

 

1、WebService寻址
与以协议无关的SOAP作为消息的载体在被客户端发往服务端以后就不再由客户端所控制了。

如果以HTTP将SOAP从客户端发往服务端,通过HTTP协议的标准动作如Get、Post进行操作,

服务处理完毕以后再通过HTTP响应发往客户端这样一次交互就完成了。可事实上,SOAP没有标准

方法来指定消息的目的地址、如何返回响应以及错误在哪等。如果消息交互变得复杂一点,这种问题

就无法解决。如:由客户端发出去的消息需经过多个服务路由处理。

WebService寻址规范正是为了解决这些问题。在WebService寻址规范中有两个重要的概念:

终结点应用、消息报 头。它可以用于在WebService中传达Service Endpoint所需要的信息,

也可为消息在WebService间传送提供地址。

 

如下所示显示终结点应用所需的信息集

<wsa:EndpointReference>
  <wsa:Address>xs:anyURI</wsa:Address>
  <wsa:ReferenceProperties>... </wsa:ReferenceProperties> ?
  <wsa:ReferenceParameters>... </wsa:ReferenceParameters> ?
  <wsa:PortType>xs:QName</wsa:PortType> ?
  <wsa:ServiceName PortName="xs:NCName"?>xs:QName</wsa:ServiceName> ?
  <wsa:Policies> ... </wsa:Policies>?
  <xs:any/>*
</wsa:EndpointReference>
 

在终结点应用所需的信息集中只有<wsa:Address>xs:anyURI</wsa:Address>是必须的,其他几个都是可选的。

 

消息报头:它是WebService寻址中定义了一些标准的SOAPHeader,它扩展并添加到SOAPHeader中。

2、逻辑地址与物理地址
物理地址是ServiceEndpoint的ListenUri属性指明的值,也就是监听地址;逻辑地址则是终结点地址,

即EndpointAddress,即SOAP消息的"To"指向的地址。

public class ServiceEndpoint
{
    // Fields
    private EndpointAddress address;
    private Uri listenUri;        
    private ListenUriMode listenUriMode;
    //其他属性
}
 

WCF客户端与服务端交互是通过物理地址,即监听地址实现的。在WCF中,服务通过物理地址

在制定的位置监听传入的消息。在WCF配置中,<endpoint>元素中address属性指定的即为逻辑

地址;listenUri指定物理地址。除非通过listenUri指定,一般逻辑地址与物理地址是相同的。

 

  如果服务端配置了物理地址,在客户端通过ClientViaBehavior告之Client服务端所使用的物理地址。

Server端配置如下:

 

<endpoint
                address="net.tcp://127.0.0.1:9999/CalculatorService"
                binding="netTcpBinding" contract="Contracts.ICalculator"  listenUri="net.tcp://127.0.0.1:3333/CalculatorService" /


 Client端配置如下:

 

<behaviors>
<endpointBehaviors>
<behavior name="myNetTcp">
<clientVia viaUri ="net.tcp://127.0.0.1:3333/CalculatorService"/>
</behavior>
</endpointBehaviors>
</behaviors>
<endpoint address="net.tcp://127.0.0.1:9999/CalculatorService" 
binding="netTcpBinding" contract="Contracts.ICalculator" name="calculatorService"  behaviorConfiguration="myNetTcp" >
</endpoint>
 

使用物理地址,客户端通过与服务端相同的物理地址发送消息。那么逻辑地址有什么用呢。?看看

EndpointAddressMessageFilter的Match方法的签名:

 public override bool Match(Message message)
    {
        if (message == null)
        {
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
        }
        Uri to = message.Headers.To;
        Uri uri = this.address.Uri;
        return (((to != null) && this.comparer.Equals(uri, to)) && this.helper.Match(message));
    }

    public override bool Match(MessageBuffer messageBuffer)
    {
        bool flag;
        if (messageBuffer == null)
        {
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
        }
        Message message = messageBuffer.CreateMessage();
        try
        {
            flag = this.Match(message);
        }
        finally
        {
            message.Close();
        }
        return flag;
    }
通过Match方法,我们可知:ChannelDispatcher通过遍历EndpointDispatcher以确定将消息发送到哪一个EndpointDispatcher时,使用逻辑地址进行判断。
3、基地址、相对地址、绝对地址
在WCF中,通过基地址技术可以为不同的Endpoint方便的配置不同的地址逻辑地址。

基地址、相对地址、绝对地址都是相对Endpoint来说的。

 

3.1 基地址

在<host>下的子元素<baseAddresses>下通过<add>指定,如下:

 

<host>             

   <baseAddresses>
      <add baseAddress="http://127.0.0.1:8888/Calculator"/>
   </baseAddresses>
</host> 

 

3.2 相对地址:

在<Endpoint >的<Address>属性中指定非完全限定地址。使用基地址时就无需为<Endpoint >指定绝对地址了。如下:

<endpoint address="Service" binding="basicHttpBinding" contract="Contracts.ICalculator" ></endpoint>  


3.3 绝对地址

直接在<Endpoint >的<Address>属性指定的终结点的完全限定地址。如:“

<endpoint
                    address="http://127.0.0.1:8888/CalculatorServices"
                    binding="basicHttpBinding" contract="Contracts.ICalculator" >
</endpoint>

 

看看对基地址、相对地址、绝对地址作如下配置是什么结果:

               <endpoint 

    address="" 
                    binding="basicHttpBinding" contract="Contracts.ICalculator" >
                </endpoint>
                <endpoint
                    address="Service"
                    binding="basicHttpBinding" contract="Contracts.ICalculator" >
                </endpoint>
                <endpoint
                    address="http://127.0.0.1:8888/CalculatorServices"
                    binding="basicHttpBinding" contract="Contracts.ICalculator" >
                </endpoint>
                <endpoint
                    address="http://127.0.0.1:9999/CalculatorService"
                    binding="basicHttpBinding" contract="Contracts.ICalculator"  listenUri="http://127.0.0.1:3333/CalculatorService" listenUriMode="Unique">
                </endpoint>
                <host>
                    <baseAddresses>
                        <add baseAddress="http://127.0.0.1:8888/Calculator"/>
                    </baseAddresses>
                </host>    

 

通过C# 控制台看看地址信息: 

 

ServiceDescription serviceDescription = host.Description;   
ServiceEndpointCollection serviceEndpoints = serviceDescription.Endpoints; 
        foreach (var serviceEndpoint in serviceEndpoints)
        {
             Console.WriteLine("----------------------------");
             Console.WriteLine("逻辑地址:"+serviceEndpoint.Address.Uri);
             Console.WriteLine("物理地址:" + serviceEndpoint.ListenUri);  

        }

输出如下:
posted @ 2012-04-16 22:58  tyb1222  阅读(8118)  评论(0编辑  收藏  举报