编写 WCF 客户端应用程序时,需要了解所调用服务的终结点地址。在许多情况下,事先并不知晓服务的终结点地址,或者服务地址会随时间变化。Discovery 客户端通道可用于编写 WCF 客户端应用程序,描述您要调用的服务,并且自动发送探测请求。如果有服务做出响应,Discovery 客户端通道会从探测响应中检索该服务的终结点地址,并使用该地址调用服务。
使用 Discovery 客户端通道
若要使用 Discovery 客户端通道,请将 DiscoveryClientBindingElement 实例添加到客户端通道堆栈。此外,也可以使用 DynamicEndpoint。如果尚不存在 DiscoveryClientBindingElement,则会自动将该绑定元素添加到绑定。
![]() |
---|
建议将 DiscoveryClientBindingElement 作为客户端通道堆栈的最顶层元素。在 DiscoveryClientBindingElement 之上添加的任何绑定元素都必须确保 ChannelFactory 或自己创建的通道不使用终结点地址或 Via 地址(传递到 CreateChannel 方法),因为它们包含的地址可能不正确。 |
DiscoveryClientBindingElement 类包含两个公共属性:
FindCriteria,用于描述您要调用的服务。
DiscoveryEndpoint,用于指定将发现消息发送到的发现终结点。
FindCriteria 属性可用于指定要搜索的服务协定、任何必需的范围 URI 以及打开通道的最大尝试次数。调用构造函数 FindCriteria 可指定协定类型。可以将范围 URI 添加到 Scopes 属性。MaxResults 属性可用于指定客户端尝试连接的最大结果数。客户端收到探测响应时,会尝试使用探测响应提供的终结点地址打开通道。如果出现异常,客户端会转到下一个探测响应,如有必要,会等待接收更多响应。客户端将继续执行此操作,直至成功打开通道或者达到最大结果数。有关这些设置的更多信息,请参见 FindCriteria。
DiscoveryEndpoint 属性可用于指定要使用的搜索终结点。该终结点通常是 UdpDiscoveryEndpoint,但也可能是任何有效的终结点。
创建用于与服务通信的绑定时,必须注意使用与服务完全相同的绑定。唯一的区别是客户端绑定在堆栈顶层有一个 DiscoveryClientBindingElement。如果服务使用系统提供的绑定之一,则创建新 CustomBinding,并在系统提供的绑定中将新绑定传递到 CustomBinding 构造函数。然后,可以对 Elements 属性调用 Insert 来添加 DiscoveryClientBindingElement。
将 DiscoveryClientBindingElement 添加到绑定并进行配置之后,即可创建 WCF 客户端类的实例、打开该实例以及调用该实例的方法。下面的示例使用 Discovery 客户端通道发现某个 WCF 服务,该服务实现 ICalculator
类(在“WCF 入门教程”中使用该类)并调用该类的 Add
方法。
// Create the DiscoveryClientBindingElement
DiscoveryClientBindingElement bindingElement = new DiscoveryClientBindingElement();
// Search for a service that implements the ICalculator interface, attempting to open
// the channel a maximum of 2 times
bindingElement.FindCriteria = new FindCriteria(typeof(ICalculator)) { MaxResults = 2 };
// Use the UdpDiscoveryEndpoint
bindingElement.DiscoveryEndpoint = new UdpDiscoveryEndpoint();
// The service uses the BasicHttpBinding, so use that and insert the DiscoveryClientBindingElement at the
// top of the stack
CustomBinding binding = new CustomBinding(new BasicHttpBinding());
binding.Elements.Insert(0,bindingElement);
try
{
// Create the WCF client and call a method
CalculatorClient client = new CalculatorClient(binding, new EndpointAddress("https://schemas.microsoft.com/dynamic"));
client.Open();
client.Add(1, 1);
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine("An exception occurred: " + ex.Message);
}
安全性和 Discovery 客户端通道
使用 Discovery 客户端通道时,同时指定了两个终结点:其中一个用于发现消息,通常为 UdpDiscoveryEndpoint;另一个是应用程序终结点。实现安全服务时,必须谨慎以确保这两个终结点的安全。有关安全性的更多信息,请参见保护服务和客户端的安全。