[英]WCF ServiceHost crashes when UserNamePasswordValidator takes too long to process
我發現一種情況,如果ServiceHost具有需要一段時間才能處理的UserNamePasswordValidator,則WCF客戶端可能會使WCF ServiceHost崩潰。 在向Microsoft提出此建議之前,我想聽聽有關解決方案的任何建議。
重現的步驟是:
僅當UserNamePasswordValidator需要一段時間來處理(例如,睡眠2秒)時,才會發生上述情況。 如果UserNamePasswordValidator立即返回,則上述情況將發生變化:
客戶端代碼如下:
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。
接下來,您應該看看可能擴展您的客戶端和服務的SendTimeout
和RecieveTimeout
。
看一下這兩個鏈接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.