Обнаружение WCF .NET 4: проблема с конфигурацией / программным определением

#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

  1. В конфигурации службы убедитесь, что имя службы совпадает с именем класса, включая пространство имен
  2. Вы должны убедиться, что служба запущена, прежде чем сможете обнаружить ее с помощью клиента. Вы можете вручную перейти к файлу .svc службы или разместить службу с помощью AppFabric и установить для автозапуска значение true (вы также можете указать это в web.config)
  3. В конфигурации сервиса вы должны указать тип, который вы собираетесь использовать в критериях поиска на клиенте

Вот пример конфигурации сервера, устанавливающей конечные точки службы. Обратите внимание, что атрибут 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, что и было моим вопросом в первую очередь 😉