Использование клиентского канала обнаружения

При написании клиентского приложения WCF необходимо знать адрес конечной точки вызываемой службы. Во многих случаях адрес конечной точки службы неизвестен заранее или может измениться со временем. Клиентский канал обнаружения позволяет создать клиентское приложение WCF, описать службу, которую необходимо вызвать, после чего клиентский канал автоматически отправит зондирующий запрос. После ответа службы клиентский канал обнаружения извлекает адрес конечной точки службы из ответа запроса и пользуется им для вызова службы.

Использование клиентского канала обнаружения

Чтобы задействовать клиентский канал обнаружения, добавьте экземпляр DiscoveryClientBindingElement в стек клиентских каналов. Можно также использовать конечную точку DynamicEndpoint, в этом случае элемент DiscoveryClientBindingElement будет автоматически добавляться к привязке, если он еще не присутствует.

Dd456780.Caution(ru-ru,VS.100).gifВнимание!
Рекомендуется в качестве самого верхнего элемента в стеке клиентских каналов задать DiscoveryClientBindingElement. Для всех элементов привязки, добавляемых поверх DiscoveryClientBindingElement, убедитесь, что ни ChannelFactory, ни создаваемый им канал не используют адрес конечной точки или адрес Via (передаваемый методу CreateChannel), поскольку правильный адрес в них может отсутствовать.

Класс DiscoveryClientBindingElement содержит два открытых свойства.

  1. FindCriteria, которое используется для описания вызываемой службы.

  2. DiscoveryEndpoint, которое указывает конечную точку обнаружения, которой необходимо отправлять сообщения.

Свойство FindCriteria позволяет указать искомый контракт службы, все необходимые URI области и максимальное количество попыток открытия канала. Тип контракта указывается при вызове конструктора FindCriteria. URI области могут быть добавлены в свойство Scopes. Свойство MaxResults позволяет задать максимальное количество результатов, с которыми клиент пытается установить соединение. При получении ответа на зондирующий запрос клиент выполняет попытку открытия канала по адресу конечной точки, полученному из ответа запроса. Если возникло исключение, то клиент переходит к следующему ответу зондирующего запроса и при необходимости ожидает получения дополнительных ответов. Это продолжается до тех пор, пока не будет успешно открыт канал или достигнуто максимальное количество результатов. Дополнительные сведения об этих параметрах см. в разделе FindCriteria.

Свойство DiscoveryEndpoint позволяет указать конечную точку обнаружения для использования. Обычно это UdpDiscoveryEndpoint, но может быть также использована любая действительная конечная точка.

При создании привязки для взаимодействия со службой должна быть указана та же привязку, что и в службе. Единственное различие заключается в том, что привязка клиента содержит DiscoveryClientBindingElement в вершине стека. Если служба использует одну из привязок, предоставленных системой, создайте новую CustomBinding и передайте привязку, предоставленную системой, конструктору CustomBinding. После этого можно добавить DiscoveryClientBindingElement, вызвав Insert для свойства Elements.

После добавления к привязке и настройки DiscoveryClientBindingElement можно создать экземпляр класса клиента WCF, открыть его и обращаться к его методам. В следующем примере показан клиентский канал обнаружения для обнаружения службы 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);
}

Безопасность и клиентский канал обнаружения

При использовании клиентского канала обнаружения указываются две конечные точки. Одна из этих точек служит для передачи сообщений обнаружения (обычно это UdpDiscoveryEndpoint), а другая является конечной точкой приложения. При реализации безопасной службы необходимо обеспечить безопасность обеих конечных точек. Сведения о безопасности Дополнительные сведения см. в разделе Защита служб и клиентов.