簡體   English   中英

UserNamePasswordValidator處理時間過長時,WCF ServiceHost崩潰

[英]WCF ServiceHost crashes when UserNamePasswordValidator takes too long to process

我發現一種情況,如果ServiceHost具有需要一段時間才能處理的UserNamePasswordValidator,則WCF客戶端可能會使WCF ServiceHost崩潰。 在向Microsoft提出此建議之前,我想聽聽有關解決方案的任何建議。

重現的步驟是:

  1. 打開一個頻道
  2. 調用需要10秒鍾才能返回的API方法。
  3. 在API方法返回之前,請關閉通道。
  4. API方法返回。 ServiceHost崩潰。

僅當UserNamePasswordValidator需要一段時間來處理(例如,睡眠2秒)時,才會發生上述情況。 如果UserNamePasswordValidator立即返回,則上述情況將發生變化:

  1. 打開一個頻道
  2. 調用需要10秒鍾才能返回的API方法。
  3. 在API方法返回之前,請關閉通道。
  4. 關閉通道等待未決的API方法調用。
  5. API方法返回。
  6. 頻道關閉。 萬事皆安。

客戶端代碼如下:

public static void Main(string[] args)
{
    var binding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);
    binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
    var identity = new DnsEndpointIdentity("Dummy");
    var endpointAddress = new EndpointAddress(new Uri("net.tcp://localhost:5000/"), identity);
    var channelFactory = new ChannelFactory<IService>(binding, endpointAddress);

    channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
    channelFactory.Credentials.UserName.UserName = "foo";
    channelFactory.Credentials.UserName.Password = "bar";

    channelFactory.Open();

    IService service = channelFactory.CreateChannel();

    ThreadPool.QueueUserWorkItem(CallPingOnChannel, service);

    Thread.Sleep(TimeSpan.FromSeconds(1));

    channelFactory.Close();
}

private static void CallPingOnChannel(object state)
{
    var result = ((state) as IService).Ping();
}

ServiceHost的設置如下:

public static void Main(string[] args)
{
    var serviceHost = new ServiceHost(typeof(Service), TcpBaseAddress);
    serviceHost.Description.Behaviors.Add(new ErrorHandler());
    var netTcpBinding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);
    netTcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
    netTcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

    serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
    serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new UserValidator();

    serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
    serviceHost.Credentials.ServiceCertificate.Certificate = GetCertificate();

    serviceHost.AddServiceEndpoint(typeof(IService), netTcpBinding, "");

    serviceHost.Open();

    Console.ReadLine();
}

而UserValidator的實現如下:

public class UserValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        Thread.Sleep(TimeSpan.FromSeconds(2));
    }
}

導致主線程崩潰的未處理異常是:

System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '10675199.02:48:05.4775807'. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '10675199.02:48:05.4775807'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

回答我自己的問題; 我向Microsoft報告了此問題,他們已經確認這是框架中的錯誤,將在即將發布的版本中修復。

鏈接: http : //connect.microsoft.com/wcf/feedback/details/622164/wcf-servicehost-crashes-when-usernamepasswordvalidator-takes-too-long-to-process

首先,您應該在客戶端代碼中捕獲System.TimeOutException。

接下來,您應該看看可能擴展您的客戶端和服務的SendTimeoutRecieveTimeout

看一下這兩個鏈接。

SendTimeOut屬性

RecieveTimeOut屬性

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM