2013-01-21 29 views
7

私はパブリッシャー加入者パターンに基づいてシステムを開発中です。 WPFアプリケーションで実行されているWCFサービスがあります。サービスに接続する多数のクライアントがあります。クライアント側もWPFです。WCFサービスでCommunicationObjectAbortedException&CommunicationObjectFaultedExceptionが発生しました

サービス:

[ServiceContract(Namespace = "http://AutoFXProfitsServer", SessionMode = SessionMode.Required, CallbackContract = typeof(ITradeMirrorClientContract))] 
    public interface ITradeMirror 
    { 
     [OperationContract] 
     string Subscribe(string userName, string password, int accountID); 

     [OperationContract] 
     bool Unsubscribe(string userName, string password, int accountID); 

     [OperationContract] 
     void PublishNewSignal(string signalInformation); 
    } 

    public interface ITradeMirrorClientContract 
    { 
     [OperationContract(IsOneWay = true)] 
     void NewSignal(string signalInformation); 
    } 

    public class NewSignalEventArgs : EventArgs 
    { 
     public string SignalInformation; 
    } 
. 
. 
. 
. 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, AutomaticSessionShutdown = false)] 
public class TradeMirrorService : DependencyObject, ITradeMirror 
{ 
. 
. 
. 
. 

public string Subscribe(string userName, string password, int accountID) 
    { 
     try 
     { 
      if (AuthenticationSuccessful) 
      { 
       _callback = OperationContext.Current.GetCallbackChannel<ITradeMirrorClientContract>(); 
       _newSignalHandler = new NewSignalEventHandler(NewSignalHandler); 
       NewSignalEvent -= _newSignalHandler; 
       NewSignalEvent += _newSignalHandler; 

       string suffixes = GetSuffixes(); 
       return suffixes; 
      } 
      else 
      { 
       return "FAILED"; 
      } 
     } 
     catch (Exception exception) 
     { 
      return "FAILED"; 
     } 
    } 

public bool Unsubscribe(string userName, string password, int accountID) 
    { 
     try 
     { 
      if (SearchHelper.UnAuthenticateUserCredentials(userName, password, accountID, _helper)) 
      { 
       _callback = OperationContext.Current.GetCallbackChannel<ITradeMirrorClientContract>(); 
       _newSignalHandler = new NewSignalEventHandler(NewSignalHandler); 
       NewSignalEvent -= _newSignalHandler; 
       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 
     catch (Exception exception) 
     { 
      return false; 
     } 
    } 

public void PublishNewSignal(string signalInformation) 
    { 
     try 
     { 
      if (HeartBeatMessage()) 
      { 

      } 
      else 
      { 
       _systemOrderID++; 

       signalInformation = TransformSignalInformation(signalInformation, _systemOrderID); 
      } 

      var e = new NewSignalEventArgs {SignalInformation = signalInformation}; 
      NewSignalEvent(this, e); 
     } 
     catch (Exception exception) 
     { 
     } 
    } 

そして、私のapp.config:

<?xml version="1.0"?> 
<configuration> 
    <system.serviceModel> 
    <bindings> 
     <netTcpBinding> 
     <binding closeTimeout="23:59:59" openTimeout="23:59:59"  receiveTimeout="23:59:59" sendTimeout="23:59:59" transactionFlow="false" transferMode="Buffered" 
      transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="1000" maxBufferPoolSize="524288" maxBufferSize="65536" 
      maxConnections="1000" maxReceivedMessageSize="65536"> 
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/> 
      <reliableSession ordered="true" inactivityTimeout="23:59:59" enabled="false"/> 
      <security mode="None"/> 
     </binding> 
     </netTcpBinding> 
    </bindings> 
    <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true--> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="false" httpGetUrl="http://95.138.188.232/autofxprofits/service"/> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 
    </system.serviceModel> 
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup> </configuration> 

システムが問題なく長期間にわたって完璧に動作私は下に私のシステムのコードスニペットを添付しています。何が起こるかというと(私はわからentirleyないですかについて)何らかの理由でサービスが時々例外でクラッシュしたということです。

CommunicationObjectAbortedException OR CommunicationObjectFaultedException

System.ServiceModel.CommunicationObjectAbortedException: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted. 

Server stack trace: 
    at System.ServiceModel.Channels.CommunicationObject.ThrowIfDisposedOrNotOpen() 
    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
    at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
    at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 

Exception rethrown at [0]: 
    at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
    at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 
    at AutoFXProfitsServer.ITradeMirrorClientContract.NewSignal(String signalInformation) 
    at AutoFXProfitsServer.TradeMirrorService.NewSignalHandler(Object sender, NewSignalEventArgs e) in D:\Work\Trade Mirror - Kumar\AutoFXToolsTradeMirror\AutoFXProfitsServer\Service.cs:line 232 
    at AutoFXProfitsServer.TradeMirrorService.PublishNewSignal(String signalInformation) in D:\Work\Trade Mirror - Kumar\AutoFXToolsTradeMirror\AutoFXProfitsServer\Service.cs:line 171 

OR、

System.ServiceModel.CommunicationObjectFaultedException: The communication object,  System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state. 

Server stack trace: 
    at System.ServiceModel.Channels.CommunicationObject.ThrowIfDisposedOrNotOpen() 
    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
    at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
    at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 

Exception rethrown at [0]: 
    at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
    at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 
    at AutoFXProfitsServer.ITradeMirrorClientContract.NewSignal(String signalInformation) 
    at AutoFXProfitsServer.TradeMirrorService.NewSignalHandler(Object sender, NewSignalEventArgs e) in D:\Work\Trade Mirror - Kumar\AutoFXToolsTradeMirror\AutoFXProfitsServer\Service.cs:line 235 
    at AutoFXProfitsServer.TradeMirrorService.NewSignalEventHandler.Invoke(Object sender, NewSignalEventArgs e) 
    at AutoFXProfitsServer.TradeMirrorService.PublishNewSignal(String signalInformation) in D:\Work\Trade Mirror - Kumar\AutoFXToolsTradeMirror\AutoFXProfitsServer\Service.cs:line 174 

だけ繰り返すために、これらの例外はPublishNewSignalメソッドで発生します。私がすべてのテストから作成した1つの理由は、クライアントが異常終了したときに発生するということです。たとえば、クライアントプロセスはタスクマネージャなどからクローズされます。

しかし、この問題は大きな苦痛であり、この安定性の問題を修正せずにforawrdを移動することはできません。コミュニケーションオブジェクトに障害が発生し、サービスがクラッシュする理由は誰にも分かりますか?

これについていくつかの肯定的なフィードバックを得ることを願っています。

ありがとうございました。 Umer

+0

ほとんどの場合、タイムアウトまたは一時的なネットワークの問題です。私は[WCFトレース](http://msdn.microsoft.com/en-us/library/ms733025.aspx)を実行して、何が起こるかについての詳細な情報があるかどうかを確認します。 –

答えて

7

いくつかの調査の後、私はこの問題を自分で解決しました。問題は、クライアントが正しくサブスクライブ解除せずに予期せず接続が切断され、サービスがドロップされたクライアントを適切に処理していなかったときです。したがって、コミュニケーションの対象は誤りになりました。 Lee'sthis questionへの回答は、私が正しい方向に考えるのを本当に助けました。さらに調査したら、私はthis discussionが問題を解決するのに非常に有用だと分かった。

1

あなたが表示した内容に基づいて、アプリケーションの起動時にWCFチャネルを開く(クライアントを作成する)ように見えますが、アプリケーションが終了するまで閉じないでください。

このアプローチにはいくつかの問題があります。あなたが走っているのは、ネットワークやサーバーを破壊すると、そのチャンネルが使用できなくなることです。

これを行う方法は、毎回WCFコールを行う必要があるときに、チャネルを開き、コールしてからチャネルを閉じることです。

このアプローチは、より堅牢でスケーラブルなソリューションの両方を提供します。

+0

ご回答いただきありがとうございます。我々は、クライアントがサービスに継続的に接続する必要があります。新しい信号が発生するたびに、サーバーはイベントを発生させ、その後、接続されたすべてのクライアントに送信されます。つまり、これはpub-subパターンです。それを行い、問題を回避する他の方法はありますか? –

+0

1つのプロジェクトでは、各WPFクライアントでWCFサーバーを実行します。クライアントが起動すると、それ自体がメインサーバーに登録されます。その後、メインサーバーは各WPFアプリケーションに対してWCF呼び出しを行うことができます。 –

関連する問題