Как настроить несколько конечных точек службы в WCF?

Мне нужны базовые рекомендации по настройке моей конфигурации WCF. Это моя первая серьезная работа с WCF (и первая публикация в stackoverflow).

У меня есть библиотека классов WCF (APILibrary), на которую я ссылаюсь в своем веб-проекте. В библиотеке wcf у меня на данный момент есть два сервиса — IAuthService и ITradeService.

В связи с этим у меня три вопроса:

1) Моя проблема (и первоначальная причина этого поста) заключается в том, что при компиляции моего приложения я могу вызывать TradeServiceCient, но не AuthServiceClient в своем веб-приложении. Последний не появляется в intellisense. У меня есть ощущение, что это связано с тем, что они используют один и тот же порт (и включена только одна конечная точка), но мне явно неясно.

2) Я пытаюсь открыть две конечные точки службы одновременно (и, вероятно, еще несколько), пока я разрабатываю и тестирую. Когда я перейду к стадии и хостингу, каждая конечная точка будет иметь свой собственный адрес. До тех пор, как мне это сделать (у меня такое ощущение, что это относится к моему вопросу выше)?

3) Я замечаю, что во многих сообщениях у людей есть примеры кода «клиент» и «сервер» «system.serviceModel». Являются ли эти уникальные файлы или теги в файле App.config, который находится в моей библиотеке WCF? Что каждый делает? В настоящее время я думаю, что у меня есть только серверная часть?

Вот что у меня сейчас есть в моем файле App.config (в моей библиотеке WCF):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <client />
    <services>
      <service behaviorConfiguration="ApiLibrary.ApiBehavior" name="SpoonSys.Api.Trade.TradeService">
        <endpoint address="" binding="wsHttpBinding" contract="SpoonSys.Api.Trade.ITradeService">
          <identity>
            <dns value="localhost:8731" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8731/Design_Time_Addresses/ApiLibrary/Trade/" />
          </baseAddresses>
        </host>
      </service>

      <service behaviorConfiguration="ApiLibrary.ApiBehavior" name="SpoonSys.Api.Authentication.AuthService">
        <endpoint address="" binding="wsHttpBinding" contract="SpoonSys.Api.Authentication.IAuthService">
          <identity>
            <dns value="localhost:8731" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8731/Design_Time_Addresses/ApiLibrary/Authentication/" />
          </baseAddresses>
        </host>
      </service>  
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ApiLibrary.ApiBehavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Моя конфигурация ASP.NET/Framework 3.5/VS 2008/С#


person Community    schedule 22.07.2009    source источник
comment
@marc_s говорит Другой вопрос, почему вы видите только одну конечную точку в вашем intellisense — вы создали свой клиентский прокси для обеих конечных точек? Поскольку это два отдельных контракта, вам понадобятся два отдельных клиентских прокси. Как вы создали клиентскую конечную точку? Можете ли вы также опубликовать конфигурацию клиента?   -  person Kiquenet    schedule 11.09.2015


Ответы (2)


Да, в вашем случае вы имеете дело только с серверной частью, так что на самом деле ваша конфигурация выглядит вполне нормально.

Единственное, что я бы изменил в вашей конфигурации, — это разделение между «baseAddress» и фактическим адресом службы. В настоящее время вы определяете весь полный адрес в своем базовом адресе - это как бы противоречит цели базового адреса. Я бы разделил так:

 <service name="SpoonSys.Api.Services"
          behaviorConfiguration="ApiLibrary.ApiBehavior" >
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8731/Design_Time_Addresses/ApiLibrary/" />
      </baseAddresses>
    </host>
    <endpoint 
       address="Trade" 
       binding="wsHttpBinding" 
       contract="SpoonSys.Api.Trade.ITradeService">
      <identity>
        <dns value="localhost:8731" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>

Таким образом, вы можете свести две ваши конечные точки в одну — базовый адрес определяет именно это — общую базу для всех остальных адресов, — в то время как конечная точка определяет детали полного адреса:

 <service name="SpoonSys.Api.Services"
          behaviorConfiguration="ApiLibrary.ApiBehavior" >
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8731/Design_Time_Addresses/ApiLibrary/" />
      </baseAddresses>
    </host>
    <endpoint 
       address="Trade" 
       binding="wsHttpBinding" 
       contract="SpoonSys.Api.Trade.ITradeService">
      <identity>
        <dns value="localhost:8731" />
      </identity>
    </endpoint>
    <endpoint 
       address="Authentication" 
       binding="wsHttpBinding" 
       contract="SpoonSys.Api.Authentication.IAuthService">
      <identity>
        <dns value="localhost:8731" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>

Это работает, если у вас есть один класс службы "SpoonSys.Api.Services", который реализует оба этих контракта службы - это совершенно нормально и иногда весьма полезно.

ЕСЛИ вам нужно иметь два отдельных класса обслуживания, каждый из которых реализует по одному интерфейсу, тогда вы не сможете свернуть свою конфигурацию таким образом — тогда вам придется использовать полную конфигурацию для двух отдельных классов обслуживания в исходном сообщении (которое мне показалось нормально).

Другой вопрос заключается в том, почему вы видите только одну конечную точку в своем intellisense — вы создали свой клиентский прокси для обеих конечных точек? Поскольку это два отдельных контракта, вам понадобятся два отдельных клиентских прокси. Как вы создали клиентскую конечную точку? Можете ли вы также опубликовать конфиг клиента?

Марк

person marc_s    schedule 22.07.2009

Я попытался сократить базовый адрес по вашему предложению. Затем я получал ошибку, когда одна служба запускалась, но не другая. Мне сказали, что конечная точка метаданных уже используется. Затем я попытался изменить свои пространства имен с SpoonSys.ApiLibrary.Authentication и SpoonSys.ApiLibrary.Trade на просто SpoonSys.ApiLibary для всех файлов классов. Тем не менее - та же ошибка. Когда я вернулся к исходной конфигурации сервера, он скомпилировался. Тем не менее, intellisense ловит только один сервис, а не другой.

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

Я заметил Client.dll в редакторе WCF для каждой конечной точки и разместил их ниже:

ENDPOINT:localhost:8731/Design_Time_Addresses/Authentication/mex

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_ITradeService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10: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="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="localhost:8731/Design_Time_Addresses/Trade/"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITradeService"
                contract="ITradeService" name="WSHttpBinding_ITradeService">
                <identity>
                    <dns value="localhost:8731" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

КОНЕЧНАЯ ТОЧКА: http://localhost:8731/Design_Time_Addresses/Trade/mex

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IAuthService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10: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="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="localhost:8731/Design_Time_Addresses/Authentication/"
                binding="wsHttp binding" bindingConfiguration="WSHttpBinding_IAuthService"
                contract="IAuthService" name="WSHttpBinding_IAuthService">
                <identity>
                    <dns value="localhost:8731" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

И, наконец, вот снова мой APP.CONFIG:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="ApiLibrary.ApiBehavior"
        name="SpoonSys.ApiLibrary.Trade.TradeService">
        <endpoint address="" binding="wsHttpBinding" contract="SpoonSys.Api.Trade.ITradeService">
          <identity>
            <dns value="localhost:8731" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8731/Design_Time_Addresses/Trade/" />
          </baseAddresses>
        </host>
      </service>
      <service behaviorConfiguration="ApiLibrary.ApiBehavior"
        name="SpoonSys.Api.Authentication.AuthService">
        <endpoint address="" binding="wsHttpBinding" contract="SpoonSys.ApiLibrary.Authentication.IAuthService">
          <identity>
            <dns value="localhost:8731" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="localhost:8731/Design_Time_Addresses/Authentication/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ApiLibrary.ApiBehavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

PS. Когда я пытаюсь отправить свой ответ, я получаю сообщение «Новые пользователи могут публиковать максимум одну гиперссылку», поэтому я удалил все ссылки «http://» в своем сообщении. Это не ошибка кода.

person Community    schedule 23.07.2009