#c# #.net #wcf #.net-4.0 #wcf-binding
#c# #.net #wcf #.net-4.0 #wcf-привязка
Вопрос:
у меня есть служба WCF с поддержкой обнаружения, и теперь я хочу подключить к ней клиент.
Проблема: Когда я использую конечную точку udp (1. ) и пытаюсь программно обнаружить службу, это работает… Когда я использую подход App.config (2. ), этого не происходит (ошибка: конечные точки не обнаружены).
Мне кажется, что «результат обнаружения udp» обоих решений должен быть одинаковым, но, к сожалению, это не так…
1. Программный подход (работает):
Код:
DiscoveryClient discClient = new DiscoveryClient("udpDiscoveryEndpoint");
FindCriteria fCriteria = new FindCriteria(typeof(IAlarmServer));
fCriteria.Duration = TimeSpan.FromSeconds(5);
fCriteria.MaxResults = 1;
FindResponse fResponse = discClient.Find(fCriteria);
EndpointAddress address = fResponse.Endpoints[0].Address;
Console.WriteLine("Address found: " address.ToString());
Конфигурация:
<system.serviceModel>
<client>
<endpoint name="udpDiscoveryEndpoint" kind="udpDiscoveryEndpoint" />
</client>
</system.serviceModel>
2. Подход с использованием App.config и подхода «интегрированный в конечную точку» (не работает!):
Код:
var Proxy = new AlarmServerClient("IAlarmServer"); // Default client generated by Visual Studio
Proxy.SomeMethod(); // throw no endpoints discovered exception
Конфигурация:
<standardEndpoints>
<dynamicEndpoint>
<standardEndpoint name="discoveryDynamicEndpointConfiguration">
<discoveryClientSettings>
<findCriteria duration="00:00:05" maxResults="1">
<types>
<add name="AlarmServiceRef.IAlarmServer"/>
</types>
</findCriteria>
<endpoint kind="udpDiscoveryEndpoint"/>
</discoveryClientSettings>
</standardEndpoint>
</dynamicEndpoint>
</standardEndpoints>
Конфигурация:
<client>
<endpoint binding="basicHttpBinding" bindingConfiguration="DefaultBasicHttpBinding" contract="AlarmServiceRef.IAlarmServer" name="IAlarmServer"
kind="dynamicEndpoint"
endpointConfiguration="discoveryDynamicEndpointConfiguration"/>
</client>
Есть идеи, почему это происходит?
Комментарии:
1. Имеет ли этот тип строгое имя? <добавить имя=»AlarmServiceRef. IAlarmServer»/>
Ответ №1:
Пара вещей, когда вы размещаете службу с обнаружением через IIS
- В конфигурации службы убедитесь, что имя службы совпадает с именем класса, включая пространство имен
- Вы должны убедиться, что служба запущена, прежде чем сможете обнаружить ее с помощью клиента. Вы можете вручную перейти к файлу .svc службы или разместить службу с помощью AppFabric и установить для автозапуска значение true (вы также можете указать это в web.config)
- В конфигурации сервиса вы должны указать тип, который вы собираетесь использовать в критериях поиска на клиенте
Вот пример конфигурации сервера, устанавливающей конечные точки службы. Обратите внимание, что атрибут service «name» является полным пространством имен для класса, который реализует службу.
Конфигурация службы
<services>
<service name="WcfDiscovery.Services.BuzzerService" behaviorConfiguration="sb1" >
<endpoint binding="basicHttpBinding" contract="WcfDiscovery.Contracts.IAlarmServer" address="" behaviorConfiguration="eb1" />
<endpoint kind="udpDiscoveryEndpoint" />
</service>
</services>
Также обязательно добавьте поведение обнаружения в службу
Конфигурация службы
<serviceBehaviors>
<behavior name="sb1">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceDiscovery />
</behavior>
</serviceBehaviors>
Поскольку я хочу, чтобы клиенты могли обнаруживать службу по типу (WcfDiscovery.Контракты.IAlarmServer) Я также должен указать это в конфигурации поведения для конечной точки (eb1)
Конфигурация службы
<endpointBehaviors>
<behavior name="eb1">
<endpointDiscovery enabled="true">
<types>
<add name="WcfDiscovery.Contracts.IAlarmServer" />
</types>
</endpointDiscovery>
</behavior>
</endpointBehaviors>
Теперь на стороне клиента я могу обнаружить службу, используя findCriteria. Обратите внимание, что тип в критериях поиска должен соответствовать типу, выданному службой (в списке типов служб)
Конфигурация клиента
<standardEndpoints>
<dynamicEndpoint>
<standardEndpoint name="dynamicEndpointConfiguration">
<discoveryClientSettings >
<endpoint kind="udpDiscoveryEndpoint" />
<findCriteria maxResults="2">
<types>
<add name="WcfDiscovery.Contracts.IAlarmServer" />
</types>
</findCriteria>
</discoveryClientSettings>
</standardEndpoint>
</dynamicEndpoint>
</standardEndpoints>
Вот конфигурация конечной точки клиента
Конфигурация клиента
<client>
<endpoint kind="dynamicEndpoint" name="endpoint" binding="basicHttpBinding" contract="WcfDiscovery.Contracts.IAlarmServer" endpointConfiguration="dynamicEndpointConfiguration" />
</client>
Наконец, я могу обнаружить службу в консольном приложении, подобном этому:
ChannelFactory<IAlarmServer> factory = new ChannelFactory<IAlarmServer>("endpoint");
var proxy = factory.CreateChannel();
Console.WriteLine(proxy.SoundAlarm());
Надеюсь, это поможет!
Ответ №2:
Вы не можете просто добавить ссылку на службу в свой клиентский проект? Он сгенерирует конфигурацию для вас.
Комментарии:
1. Нет, потому что это сгенерирует ссылку с фиксированным ip / адресом
2. Да, но вы можете переопределить это при создании экземпляра вашего прокси.
3. Конечно, но у меня все еще нет действительной конфигурации для моего обнаружения udp, что и было моим вопросом в первую очередь 😉