Увеличение времени ожидания WCF просто увеличивает время, необходимое клиенту для подтверждения ошибки - PullRequest
1 голос
/ 30 ноября 2010

У нас есть служба wcf, которая вызывает медленный метод на стороне сервера.Этот метод в основном создает файл на сервере, а затем возвращает путь, чтобы клиент мог загрузить этот файл.

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

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

Еще один, возможно, важный момент - у меня есть другие клиенты, которые будут делать несколько разныхзапросы к серверу во время этого процесса, но я не уверен, является ли это актуальным.

Конфигурация сервера:

<behaviors>
 <serviceBehaviors>     
    <behavior name="WebServiceBehavior">
     <serviceMetadata httpsGetEnabled="true" />
     <serviceDebug includeExceptionDetailInFaults="true" />
     <dataContractSerializer maxItemsInObjectGraph="2147483647" />
     <serviceCredentials>
         <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WebServiceConsumerValidator" />
     </serviceCredentials>
    </behavior>  
 </serviceBehaviors>
</behaviors>    
<bindings>
    <basicHttpBinding>
        <binding name="WebServiceBinding" maxReceivedMessageSize="2147483647" closeTimeout="01:00:00" openTimeout="01:00:00" receiveTimeout="01:00:00" sendTimeout="01:00:00">
            <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/>
            <security mode="TransportWithMessageCredential" >
                <message clientCredentialType="UserName" />
                <transport clientCredentialType="None" proxyCredentialType="None" />
            </security>
        </binding>
    </basicHttpBinding>
</bindings>
<services>
    <service behaviorConfiguration="WebServiceBehavior" name="AlarmNotifierWebService">
        <endpoint address="" binding="basicHttpBinding" contract="IAlarmNotifierWebService" bindingConfiguration="WebServiceBinding">
            <identity>
                <dns value="localhost"/>
            </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
    </service>
</services>

Конфигурация клиента

    <bindings>
         <binding name="LiveManagementWebService" closeTimeout="01:00:00" openTimeout="01:00:00" receiveTimeout="01:00:00" sendTimeout="01:00:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
 <behaviors>
  <endpointBehaviors>
    <behavior name="myEndpointBehaviour">
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
  </endpointBehaviors>
</behaviors>

<client>
  <endpoint address="https://myserver.com/WebServices/ManagementWebService.svc" binding="basicHttpBinding" bindingConfiguration="LiveManagementWebService" contract="IManagementWebService" name="LiveManagementWebService" behaviorConfiguration="myEndpointBehaviour"/>
</client>

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

Код вызова:

string downloadPath;
using (var managementWebServiceClient = new ManagementWebServiceClient(App.ManagementWebServiceClientName))
{
       managementWebServiceClient.ClientCredentials.UserName.UserName = "username";
       managementWebServiceClient.ClientCredentials.UserName.Password = "password";
       managementWebServiceClient.Open();
       // never gets past the following statement:
       downloadPath = managementWebServiceClient.BuildFileAndReturnDownloadUrl("someArg1", "someArg2");        
       managementWebServiceClient.Close();
}

//Fetch the file
var webClient = new System.Net.WebClient();                
webClient.DownloadFile(downloadPath , "filename.sdf");

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

Ответы [ 2 ]

0 голосов
/ 01 декабря 2010

Судя по вашей информации, нет ничего очевидного, что могло бы вызвать проблему.

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

  • Подключите VS (работает под Администратором) к w3wp.exe на сервере и отладьте на стороне сервера
  • Используйте Fiddler, чтобы увидеть, отправляются ли на сервер какие-либо пакеты и каков ответ
  • Пользовательский Sysinternal TcpView, чтобы увидеть, как порты открываются и закрываются на клиенте. Здесь вы также можете обнаружить проблемы с брандмауэром.

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

0 голосов
/ 01 декабря 2010

Какой InstanceContextMode вы используете?

Если вы внедряете службу как Singleton, могут возникнуть проблемы с параллелизмом.

Попробуйте установить параллелизм на несколько:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,
                 ConcurrencyMode=ConcurrencyMode.Multiple)]
class AlarmNotifierWebService : IAlarmNotifierWebService
{
   // ...
}

Еще одна попытка - что произойдет, если вы повысите уровень регулирования (количество допустимых одновременных подключений)

<behavior name="WebServiceBehavior">
     <serviceThrottling maxConcurrentCalls="32" /> <!-- The default value is 16 -->
     <serviceMetadata httpsGetEnabled="true" />
     <serviceDebug includeExceptionDetailInFaults="true" />
     <dataContractSerializer maxItemsInObjectGraph="2147483647" />
     <serviceCredentials>
         <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WebServiceConsumerValidator" />
     </serviceCredentials>
    </behavior> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...