При настройке клиента и сервера WCF, как синхронизируются файлы конфигурации?

В большинстве примеров WCF показано, как настроить клиент и сервер WCF. Теперь, что произойдет, если вы немного измените конфигурацию между ними? Я имею в виду, кто имеет последнее слово?

Возьмите эту конфигурацию клиента, например:

<configuration>
<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_ISampleService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Message">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" establishSecurityContext="true" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:8080/SampleService" binding="wsHttpBinding"
            bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
            name="WSHttpBinding_ISampleService">
        </endpoint>
    </client>
</system.serviceModel>

Обычно серверная сторона будет иметь то же самое связывание, настроенное на его открытом сервере.

Но что происходит сейчас, если на стороне сервера определено openTimeout = 00:00:30. Какой будет тайм-аут? Кто выигрывает? Я делаю тот же вопрос для всех других параметров.

Все это кажется большим беспорядком, как вы можете сказать, для каждого элемента конфигурации (привязки, клиента, службы, поведения и т.д.) и всех их деталей, какие параметры необходимы и на какой стороне (клиент или сервер)?

Кажется, вы могли бы определить всю привязку со всеми параметрами тайм-аута на стороне сервера, а на стороне клиента просто установить минимально необходимую конфигурацию, чтобы все параметры с сервера были приняты. Но теперь, какие минимально требуемые параметры на клиенте, рассматривающие сервер, имеют более глубокую конфигурацию?

Какова наилучшая практика при настройке клиента и сервера с использованием WCF в отношении параметров для каждого элемента конфигурации: привязки, службы, клиент/конечная точка и поведение?

Когда конфликтующие параметры определяются между клиентом и сервером, как обрабатывает WCF?

Ответы

Ответ 1

Чтобы ответить на ваш запрос в вашем последнем комментарии к моему предыдущему ответу, я попытался придумать свой подход к тому, как я буду создавать (и изменять) конфигурацию сервера и клиента для любой данной службы. Это основано на обеих теориях, которые я читал (книги, блоги), в том, что я узнал в Juval Lowy WCF Master Class, и довольно много практического опыта с несколькими крупными проектами внедрения услуг - это невозможно в одном месте, в Интернете или в книге.... так вот он идет:

Я бы начал с нуля. Сначала подумайте о своем сервисе:

  • на каком адресе живет ваш сервис?
  • какие привязки вы хотите поддержать?

Самый простой сценарий: одиночная служба, одиночная конечная точка, basicHttpBinding, все значения по умолчанию

Конфигурация службы:

<system.serviceModel>
   <services>
      <service name="YourNamespace.YourServiceClass">
         <endpoint name="Default"
             address="http://YourServer/SomeVirtualDirectory/YourService.svc"
             binding="basicHttpBinding"
             contract="YourNamespace.IYourServiceContract" />
      </service>
   </services>
</system.serviceModel>

Соответствующая конфигурация клиента:

<system.serviceModel>
   <client name="Default">
      <endpoint name="Default"
          address="http://YourServer/SomeVirtualDirectory/YourService.svc"
          binding="basicHttpBinding"
          contract="YourClientProxyNamespace.IYourServiceContract" />
   </client>
</system.serviceModel>

Тогда только когда-нибудь измените что-то, если вы действительно должны! И больше всего: НИКОГДА НИКОГДА не позволяйте Visual Studio (Добавить ссылку на службу) или svcutil.exe испортить вашу конфигурацию! Защитите его, как яблоко вашего глаза!

Затем: если, например, ваша передача данных занимает больше времени, чем позволяет таймаут по умолчанию, равный 1 минутам, и измените эту единую настройку как на стороне обслуживания, так и на стороне клиента. Сделайте это, указав настраиваемую конфигурацию привязки и указав ее на конечные точки - , но измените только это - не больше! Оставьте все остальное как есть, со значениями по умолчанию. Никогда не изменяйте ничего, если вы не должны (и знать, что делаете, и почему вы это делаете).

Имейте в виду: sendTimeout на клиенте (время, разрешенное до отправки всего сообщения) будет соответствовать receiveTimeout на сервере - время, в течение которого будет отправлено целое сообщение (см. это отличный пост в блоге и этот форум форума MSDN для получения дополнительной информации)

Конфигурация службы:

 <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="ExtendedTimeout"
                 receiveTimeout="00:05:00" />
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="YourNamespace.YourServiceClass">
        <endpoint name="Default"
            address="http://YourServer/SomeVirtualDirectory/YourService.svc"
            binding="basicHttpBinding"
            bindingConfiguration="ExtendedTimeout"
            contract="YourNamespace.IYourServiceContract" />
      </service>
    </services>
  </system.serviceModel>

Соответствующая конфигурация клиента:

<system.serviceModel>
   <bindings>
      <basicHttpBinding>
         <binding name="ExtendedTimeout"
                  sendTimeout="00:05:00" />
      </basicHttpBinding>
   </bindings>
   <client name="Default">
      <endpoint name="Default"
          address="http://YourServer/SomeVirtualDirectory/YourService.svc"
          binding="basicHttpBinding"
          bindingConfiguration="ExtendedTimeout"
          contract="YourClientProxyNamespace.IYourServiceContract" />
   </client>
</system.serviceModel>

Поскольку вам нужны другие изменения, например несколько конечных точек на стороне службы, или локальные параметры, такие как bypassProxyOnLocal - адаптируйте свой конфиг, делайте это осторожно, шаг за шагом, вручную и считайте свою конфигурацию чрезвычайно важной частью всего вашего сервис - позаботьтесь о нем, поместите его в управление версиями и т.д.

Ответ 2

Если заданный тайм-аут примерно то же самое в конце, на клиенте и на сервере, а два значения не совпадают, более короткий тайм-аут "выигрывает" - независимо от того, определен ли он на сервере или клиенте,

Большинство других вещей, таких как адреса, привязки и т.д. должны совпадать - в противном случае связь невозможна...

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

Но как только одна конечная точка обслуживания была выбрана для вашего соединения, такие настройки, как привязки, протоколы, безопасность, надежность и т.д., должны точно соответствовать.

Также: конфигурация по умолчанию, которую генерируют инструменты командной строки Visual Studio Add Service Reference или svcutil.exe, является катастрофически плохим - они содержат слишком много настроек, которые отражают значения по умолчанию, что делает его очень трудно понять, что действительно необходимо, а что нет.

В этом отношении я бы рекомендовал посмотреть DotNet Rocks TV Show # 122: Мигель Кастро на Extreme WCF, в котором Мигель прекрасно показывает насколько легко создавать эти конфигурации вручную, и тогда вы полностью понимаете, что вы делаете! Очень рекомендуется!