增加WCF超时只会增加客户端确认错误所需的时间

时间:2010-11-30 20:48:56

标签: wcf

我们有一个调用慢速服务器端方法的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>

请注意,maxed out值是因为此服务在某些情况下会返回大量数据。

主叫代码:

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 :(得分:0)

您使用的InstanceContextMode是什么?

如果您将服务实现为Singleton,则可能存在并发问题。

尝试将并发设置为Multiple:

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

答案 1 :(得分:0)

根据您的信息,没有什么明显可能导致问题。

您的第一步必须确保客户端的呼叫实际上已到达服务器。为了确定这一点,您有以下几种选择:

  • 将VS(在管理员下运行)连接到服务器上的w3wp.exe并调试服务器端
  • 使用Fiddler查看是否有任何数据包进入服务器以及响应是什么
  • 用户Sysinternal的TcpView可以查看客户端上打开和关闭的端口。你也可以在这里发现防火墙问题。

确定此事实后,请相应更新您的问题,我会根据您的调查结果更新我的答案。