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

У меня есть служба 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());

Config:

<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

Config:

<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>

Config:

  <client>
     <endpoint binding="basicHttpBinding" bindingConfiguration="DefaultBasicHttpBinding" contract="AlarmServiceRef.IAlarmServer" name="IAlarmServer"
            kind="dynamicEndpoint"
            endpointConfiguration="discoveryDynamicEndpointConfiguration"/>
  </client>

Любые идеи, почему это происходит?

Ответ 1

Несколько вещей, когда вы размещаете сервис с обнаружением через IIS

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

Вот пример конфигурации сервера, устанавливающий конечные точки службы. Обратите внимание, что атрибут "имя" службы является полным пространством имен для класса, который реализует эту службу.

Service Config

<services>
      <service name="WcfDiscovery.Services.BuzzerService" behaviorConfiguration="sb1" >
        <endpoint binding="basicHttpBinding" contract="WcfDiscovery.Contracts.IAlarmServer" address="" behaviorConfiguration="eb1"  />
        <endpoint kind="udpDiscoveryEndpoint"  />
      </service>
    </services>

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

Service Config

<serviceBehaviors>
        <behavior name="sb1">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceDiscovery />
        </behavior>
      </serviceBehaviors>

Поскольку я хочу, чтобы клиенты могли обнаружить службу по типу (WcfDiscovery.Contracts.IAlarmServer), я должен также указать, что в конфигурации поведения для конечной точки (eb1)

Service Config

<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

Не можете ли вы добавить ссылку на службу в свой проект клиента? Он будет генерировать конфигурацию для вас.