编写 WCF 客户端应用程序时,需要知道要调用的服务的终结点地址。 在许多情况下,服务终结点地址在一段时间内未知,或者服务地址会随着时间推移而变化。 使用发现客户端通道可以编写 WCF 客户端应用程序、描述要调用的服务,以及客户端通道自动发送探测请求。 如果有服务做出响应,Discovery 客户端通道会从探测响应中检索该服务的终结点地址,并使用该地址调用服务。
使用 Discovery 客户端通道
若要使用发现客户端通道,请将该 DiscoveryClientBindingElement 实例添加到客户端通道堆栈。 或者,您可以使用DynamicEndpoint,如果尚未出现,则自动添加一个DiscoveryClientBindingElement到您的绑定中。
谨慎
建议 DiscoveryClientBindingElement 是客户端通道堆栈上最顶层的元素。 添加到DiscoveryClientBindingElement顶部的任何绑定元素都必须确保它所创建的ChannelFactory或通道不使用终结点地址或传递给Via
方法的CreateChannel
地址,因为它们可能不包含正确的地址。
该 DiscoveryClientBindingElement 类包含两个公共属性:
FindCriteria,用于描述要调用的服务。
DiscoveryEndpointProvider ,指定要向其发送发现消息的发现终结点。
FindCriteria 属性可用于指定要搜索的服务协定、任何必需的范围 URI 以及打开通道的最大尝试次数。 协定类型是通过调用构造函数 FindCriteria指定的。 范围 URI 可被添加到 Scopes 属性。 该 MaxResults 属性允许指定客户端尝试连接到的最大结果数。 收到探测响应时,客户端会尝试使用探测响应中的终结点地址打开通道。 如果发生异常,客户端将转到下一个探测响应,并在必要时等待接收更多响应。 它会继续进行这一操作,直到通道成功打开或达到结果数量上限。 有关这些设置的详细信息,请参阅 FindCriteria。
使用该 DiscoveryEndpointProvider 属性可以指定要使用的发现终结点。 通常,这是一个 UdpDiscoveryEndpoint,但它可以是任何有效的终结点。
创建用于与服务通信的绑定时,必须确保使用与服务完全相同的绑定。 唯一的区别是客户端绑定在堆栈顶层有一个 DiscoveryClientBindingElement。 如果服务使用的是系统提供的绑定之一,请创建一个新的 CustomBinding 绑定,并将系统提供的绑定 CustomBinding 传递给构造函数。 然后,可以通过对DiscoveryClientBindingElement属性调用Insert
来添加Elements。
在您将 DiscoveryClientBindingElement 添加到绑定并对其进行配置后,可以创建 WCF 客户端类的实例,打开该实例,然后调用它的方法。 以下示例使用发现客户端通道来发现实现 ICalculator
类(在入门 WCF 教程中使用的)并调用其方法的 Add
WCF 服务。
// 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("http://schemas.microsoft.com/dynamic"));
client.Open();
client.Add(1, 1);
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine("An exception occurred: " + ex.Message);
}
安全性和 Discovery 客户端通道
使用发现客户端通道时,将指定两个终结点。 一个用于发现消息,通常 UdpDiscoveryEndpoint,另一个是应用程序终结点。 实现安全服务时,必须小心保护这两个终结点。 有关安全性的详细信息,请参阅 保护服务和客户端。