2013-01-16 36 views
0

WCF服務(服務器)運行良好了一段時間,但比它竟然跟例外崩潰,此異常被記錄在AppDomain.CurrentDomain.UnhandledExceptionWCF服務器側面碰撞CommunicationObjectFaultedException:

System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.SecurityChannelListener`1+SecurityReplySessionChannel[System.ServiceModel.Channels.IReplySessionChannel], cannot be used for communication because it is in the Faulted state. 
    at System.ServiceModel.Channels.CommunicationObject.ThrowIfFaulted() 
    at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.StartInnerReceive() 
    at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.OnFaultSent() 
    at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.OnInnerReceiveDone() 
    at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.StartInnerReceive() 
    at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.Start() 
    at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveRequestAndVerifySecurityAsyncResult.ReceiveMessage(Object state) 
    at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) 
    at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) 
    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) 

有沒有xml配置,一切都在運行時配置。 服務上下文是單個,併發是多個。

我們已禁用重播檢測。我們的用戶在PC上設置了錯誤的日期時間問題,所以我們被迫「禁用」時間偏差。 Net.Tcp綁定用於通信,我們使用回調。

使用自定義錯誤處理程序,HandleError始終返回false。

當前解決方案:服務設置爲在崩潰後自動重新啓動,但這比不令人滿意。


配置(常變量的值替換):

Uri tcpBaseAddress = new Uri(String.Format("net.tcp://localhost:{0}", MyMwcNetworkingConstants.NETWORKING_PORT_MASTER_SERVER_NEW)); 

// create the net.tcp binding for the service endpoint 
NetTcpBinding ntcBinding = new NetTcpBinding(); 
ntcBinding.Security.Mode = SecurityMode.None; 
ntcBinding.MaxBufferPoolSize = 1024*1024; 
ntcBinding.MaxBufferSize = 10*1024; 
ntcBinding.MaxConnections = 500; 
ntcBinding.ListenBacklog = 500; 
ntcBinding.MaxReceivedMessageSize = 10*1024; 
ntcBinding.ReaderQuotas.MaxArrayLength = 10*1024; 
ntcBinding.ReaderQuotas.MaxBytesPerRead = 10*1024; 
ntcBinding.SendTimeout = 90s; 
ntcBinding.ReceiveTimeout = 90s; 
ntcBinding.Security.Mode = SecurityMode.Message; 
ntcBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; 
ntcBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None; 
ntcBinding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.None; 

m_host = new System.ServiceModel.ServiceHost(Service, tcpBaseAddress); 
m_host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new MyUserValidator(); 
m_host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom; 
m_host.Credentials.ServiceCertificate.Certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(MyMasterConstants.MASTER_CERTIFICATE, string.Empty); 
m_host.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new MyCertificateValidator(String.Empty); 
m_host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None; 

var endpoint = m_host.AddServiceEndpoint(typeof(IMyMasterService), MyCustomBinding.DecorateBinding(ntcBinding, MyMasterConstants.WCF_MAX_CLIENT_COUNT), tcpBaseAddress); 
m_host.Open(); 

有我的自定義綁定:

public static class MyCustomBinding 
{ 
    public static Binding DecorateBinding(Binding binding, int? maxNegotiationCount) 
    { 
     CustomBinding customBinding = new CustomBinding(binding); 
     SymmetricSecurityBindingElement security = customBinding.Elements.Find<SymmetricSecurityBindingElement>(); 
     if (security != null) 
     { 
      security.IncludeTimestamp = false; 
      security.LocalClientSettings.DetectReplays = false; 
      security.LocalServiceSettings.DetectReplays = false; 
      security.LocalClientSettings.MaxClockSkew = TimeSpan.MaxValue; 
      security.LocalServiceSettings.MaxClockSkew = TimeSpan.MaxValue; 
      security.LocalClientSettings.SessionKeyRenewalInterval = TimeSpan.MaxValue; 
      security.LocalServiceSettings.SessionKeyRenewalInterval = TimeSpan.FromMilliseconds(Int32.MaxValue); 

      if (maxNegotiationCount.HasValue) 
      { 
       security.LocalServiceSettings.MaxPendingSessions = maxNegotiationCount.Value; 
       security.LocalServiceSettings.MaxStatefulNegotiations = maxNegotiationCount.Value; 
      } 

      // Get the System.ServiceModel.Security.Tokens.SecureConversationSecurityTokenParameters 
      SecureConversationSecurityTokenParameters secureTokenParams = (SecureConversationSecurityTokenParameters)security.ProtectionTokenParameters; 

      // From the collection, get the bootstrap element. 
      SecurityBindingElement bootstrap = secureTokenParams.BootstrapSecurityBindingElement; 

      // Set the MaxClockSkew on the bootstrap element. 
      bootstrap.IncludeTimestamp = false; 
      bootstrap.LocalClientSettings.DetectReplays = false; 
      bootstrap.LocalServiceSettings.DetectReplays = false; 
      bootstrap.LocalClientSettings.MaxClockSkew = TimeSpan.MaxValue; 
      bootstrap.LocalServiceSettings.MaxClockSkew = TimeSpan.MaxValue; 
      bootstrap.LocalClientSettings.SessionKeyRenewalInterval = TimeSpan.MaxValue; 
      bootstrap.LocalServiceSettings.SessionKeyRenewalInterval = TimeSpan.FromMilliseconds(Int32.MaxValue); 

      if (maxNegotiationCount.HasValue) 
      { 
       bootstrap.LocalServiceSettings.MaxPendingSessions = maxNegotiationCount.Value; 
       bootstrap.LocalServiceSettings.MaxStatefulNegotiations = maxNegotiationCount.Value; 
      } 

      return customBinding; 
     } 
     else 
     { 
      return binding; 
     } 
    } 

    public static Binding DecorateBinding(Binding binding) 
    { 
     return DecorateBinding(binding, null); 
    } 
} 
+0

故障狀態可能意味着很多事情(不可能解析配置等)。 將綁定更改爲basicHttpBinding - 更易於調試。 –

+0

配置WCF跟蹤以獲取更詳細的錯誤消息。就像彼得說的那樣,斷定狀態可能意味着很多事情。 –

+0

@ PeterLarsen'CPH':我無法在DEV上重現此問題,它只能在PRODUCTION上重現。而且我無法改變對生產的約束。我會嘗試在DEV上重現,但需要很多種不同的請求,而且需要很長時間才能重現。它每天生產一次就會崩潰。 –

回答

1

我在完全相同的情況是,你( WCF服務在生產中隨機崩潰,無法在Dev中複製,堆棧跟蹤與您的相同)。我找到了以下知識庫,然後馬上試用:http://support.microsoft.com/kb/2600907/en-us。 「此修補程序尚未完全測試」阻止我現在應用它。

讓我知道你是否嘗試過,它可以解決你的問題。希望這可以幫助。