WCF サービス (サーバー) はしばらく正常に動作していますが、例外で予期せずクラッシュするため、この例外はAppDomain.CurrentDomain.UnhandledExceptionに記録されます。
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);
}
}