WCF中的几种地址总结
WebService寻址开始,总结一下WCF中的几种地址。
如果以HTTP将SOAP从客户端发往服务端,通过HTTP协议的标准动作如Get、Post进行操作,
服务处理完毕以后再通过HTTP响应发往客户端这样一次交互就完成了。可事实上,SOAP没有标准
方法来指定消息的目的地址、如何返回响应以及错误在哪等。如果消息交互变得复杂一点,这种问题
就无法解决。如:由客户端发出去的消息需经过多个服务路由处理。
终结点应用、消息报 头。它可以用于在WebService中传达Service Endpoint所需要的信息,
也可为消息在WebService间传送提供地址。
如下所示显示终结点应用所需的信息集
<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中。
即EndpointAddress,即SOAP消息的"To"指向的地址。
{
// Fields
private EndpointAddress address;
private Uri listenUri;
private ListenUriMode listenUriMode;
//其他属性
}
WCF客户端与服务端交互是通过物理地址,即监听地址实现的。在WCF中,服务通过物理地址
在制定的位置监听传入的消息。在WCF配置中,<endpoint>元素中address属性指定的即为逻辑
地址;listenUri指定物理地址。除非通过listenUri指定,一般逻辑地址与物理地址是相同的。
如果服务端配置了物理地址,在客户端通过ClientViaBehavior告之Client服务端所使用的物理地址。
address="net.tcp://127.0.0.1:9999/CalculatorService"
binding="netTcpBinding" contract="Contracts.ICalculator" listenUri="net.tcp://127.0.0.1:3333/CalculatorService" />
Client端配置如下:
使用物理地址,客户端通过与服务端相同的物理地址发送消息。那么逻辑地址有什么用呢。?看看
EndpointAddressMessageFilter的Match方法的签名:
{
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;
}
基地址、相对地址、绝对地址都是相对Endpoint来说的。
3.1 基地址:
在<host>下的子元素<baseAddresses>下通过<add>指定,如下:
<baseAddresses>
<add baseAddress="http://127.0.0.1:8888/Calculator"/>
</baseAddresses>
</host>
3.2 相对地址:
在<Endpoint >的<Address>属性中指定非完全限定地址。使用基地址时就无需为<Endpoint >指定绝对地址了。如下:
3.3 绝对地址:
直接在<Endpoint >的<Address>属性指定的终结点的完全限定地址。如:“
address="http://127.0.0.1:8888/CalculatorServices"
binding="basicHttpBinding" contract="Contracts.ICalculator" >
</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# 控制台看看地址信息:
ServiceEndpointCollection serviceEndpoints = serviceDescription.Endpoints;
foreach (var serviceEndpoint in serviceEndpoints)
{
Console.WriteLine("----------------------------");
Console.WriteLine("逻辑地址:"+serviceEndpoint.Address.Uri);
Console.WriteLine("物理地址:" + serviceEndpoint.ListenUri);
}