使用 Discovery 客户端通道

编写 WCF 客户端应用程序时,需要知道要调用的服务的终结点地址。 在许多情况下,服务终结点地址在一段时间内未知,或者服务地址会随着时间推移而变化。 使用发现客户端通道可以编写 WCF 客户端应用程序、描述要调用的服务,以及客户端通道自动发送探测请求。 如果有服务做出响应,Discovery 客户端通道会从探测响应中检索该服务的终结点地址,并使用该地址调用服务。

使用 Discovery 客户端通道

若要使用发现客户端通道,请将该 DiscoveryClientBindingElement 实例添加到客户端通道堆栈。 或者,您可以使用DynamicEndpoint,如果尚未出现,则自动添加一个DiscoveryClientBindingElement到您的绑定中。

谨慎

建议 DiscoveryClientBindingElement 是客户端通道堆栈上最顶层的元素。 添加到DiscoveryClientBindingElement顶部的任何绑定元素都必须确保它所创建的ChannelFactory或通道不使用终结点地址或传递给Via方法的CreateChannel地址,因为它们可能不包含正确的地址。

DiscoveryClientBindingElement 类包含两个公共属性:

  1. FindCriteria,用于描述要调用的服务。

  2. 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,另一个是应用程序终结点。 实现安全服务时,必须小心保护这两个终结点。 有关安全性的详细信息,请参阅 保护服务和客户端