2016-12-06 16 views
0

以下を考慮してください:WCFクライアントが複数の契約(複数契約)を使用していた契約を(サーバー側で)どのように把握するのですか?

マスターサーバーと通信できる別の場所に1台のマスターサーバーと複数のサーバーがあります。さらに(GUI)クライアントは各サーバーに接続できます。

だから私は、誰もが知られているパブリック・インタフェースがあります。マスターサーバーは、それに接続されたサーバ上の要求をトリガすることができるよう

[ServiceContract(SessionMode = SessionMode.Required)] 
public interface IBaseService 
{ 
    [OperationContract] 
    void Subscribe(); 

    [OperationContract] 
    void Unsubscribe(); 
} 

をさらにサーバは、コールバック契約をサポートしています。

[ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)] 
interface IServerService : IBaseService 
{ 
} 

public interface ICallback 
{ 
    [OperationContract] 
    [FaultContract(typeof(ExceptionDetail))] 
    void TheCallback(); 
} 

つまり、サーバには2つの実装契約があります。 したがって、マスターサーバー上のすべてのサブスクライバ(SubscribeのキャッシュはすべてOperationContext)を繰り返し、クライアントのコールバック契約を呼び出すと、タイムアウトになります。 私は何らかのContractMismatchを期待していました。何か(そしてすぐに!)しかし操作のタイムアウト?!?

クライアントが接続に使用した契約名(OperationContext.Current)も把握しようとしました。しかしそれも成功しなかった。どちらの場合も、IServerServiceOperationContext.Current.EndpointDispatcher.ContractNameと表示されています。

接続時にクライアントが使用したのは、OperationContractでしたか?

もちろん、私は方法SubscribeServerでサーバーインターフェイスを拡張することができますが、それは私にはかなり醜いようです。

EDIT

私はMessageInspectorを実装していた提案されたよう。

> XYZ.exe!XYZ.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext) Line 99 C# 
System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.AfterReceiveRequestCore(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x86 bytes 
System.ServiceModel.dll!System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(ref System.ServiceModel.Dispatcher.MessageRpc rpc) + 0x37 bytes 
System.ServiceModel.dll!System.ServiceModel.Dispatcher.MessageRpc.Process(bool isOperationContextSet) + 0x151 bytes 
System.ServiceModel.dll!System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(System.ServiceModel.Channels.RequestContext request, bool cleanThread, System.ServiceModel.OperationContext currentOperationContext) + 0x644 bytes 
System.ServiceModel.dll!System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(System.ServiceModel.Channels.RequestContext request, System.ServiceModel.OperationContext currentOperationContext) + 0x1d2 bytes  
System.ServiceModel.dll!System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(System.IAsyncResult result) + 0x4b bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(System.IAsyncResult result) + 0x32 bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.AsyncResult.Complete(bool completedSynchronously) + 0x16b bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.InputQueue<System.ServiceModel.Channels.Message>.AsyncQueueReader.Set(System.Runtime.InputQueue<System.ServiceModel.Channels.Message>.Item item) + 0x41 bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.InputQueue<System.ServiceModel.Channels.Message>.Dispatch() + 0x320 bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.ReliableDuplexSessionChannel.ProcessDuplexMessage(System.ServiceModel.Channels.WsrmMessageInfo info) + 0x7cb bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.ServerReliableDuplexSessionChannel.ProcessMessage(System.ServiceModel.Channels.WsrmMessageInfo info) + 0x2a7 bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.ReliableDuplexSessionChannel.HandleReceiveComplete(System.IAsyncResult result) + 0x1fa bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.ReliableDuplexSessionChannel.OnReceiveCompletedStatic(System.IAsyncResult result) + 0x86 bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(System.IAsyncResult result) + 0x32 bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.AsyncResult.Complete(bool completedSynchronously) + 0x16b bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.ReliableChannelBinder<System.__Canon>.InputAsyncResult<System.__Canon>.OnInputComplete(System.IAsyncResult result) + 0x7a bytes  
System.Runtime.DurableInstancing.dll!System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(System.IAsyncResult result) + 0x32 bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.AsyncResult.Complete(bool completedSynchronously) + 0x16b bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.FramingDuplexSessionChannel.TryReceiveAsyncResult.OnReceive(System.IAsyncResult result) + 0xa9 bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(System.IAsyncResult result) + 0x32 bytes 
System.Runtime.DurableInstancing.dll!System.Runtime.AsyncResult.Complete(bool completedSynchronously) + 0x16b bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.OnReceiveComplete(object state) + 0x82 bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.SessionConnectionReader.OnAsyncReadComplete(object state) + 0x175 bytes  
System.Runtime.DurableInstancing.dll!System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(System.IAsyncResult result) + 0x32 bytes 
System.dll!System.Net.LazyAsyncResult.Complete(System.IntPtr userToken) + 0xc5 bytes  
System.dll!System.Net.Security.NegotiateStream.ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest) + 0x126 bytes  
System.dll!System.Net.Security.NegotiateStream.ReadCallback(System.Net.AsyncProtocolRequest asyncRequest) + 0xea bytes 
System.dll!System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(int bytes) + 0x32 bytes 
System.dll!System.Net.FixedSizeReader.ReadCallback(System.IAsyncResult transportResult) + 0x9c bytes  
System.Runtime.DurableInstancing.dll!System.Runtime.AsyncResult.Complete(bool completedSynchronously) + 0x16b bytes 
System.ServiceModel.dll!System.ServiceModel.Channels.ConnectionStream.ReadAsyncResult.OnAsyncReadComplete(object state) + 0xa2 bytes  
System.ServiceModel.dll!System.ServiceModel.Channels.SocketConnection.AsyncReadCallback(bool haveResult, int error, int bytesRead) + 0x19b bytes  
System.Runtime.DurableInstancing.dll!System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(uint error, uint bytesRead, System.Threading.NativeOverlapped* nativeOverlapped) + 0x40 bytes 
mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x96 bytes  
[Native to Managed Transition] 

私のサービスクラスがコールバックを持っているIServerServiceを実装する場合、これはどういう意味:さらに多くの奇妙なコールスタックがすでにReliableDuplexSessionChannelが含まれていることですいただきました。しかしAfterReceiveRequestにIClientChannelが正常にICallback

にキャストすることができますすべての接続クライアントがデュプレックスプロキシ経由でルーティングされていることを定義していますか?クライアントが使用した(または実装された)契約に関係なく

答えて

0

サーバー側では、メッセージデータが入っている別のオブジェクトがOperationContext.Current.Hostです。

契約に関する情報を得ることができます。ここではいくつかのデータが入手可能です:

インタフェース名OperationContext.Current.Host.ImplementedContracts.FirstOrDefault().Value.Name

インタフェース名前空間OperationContext.Current.Host.ImplementedContracts.FirstOrDefault().Value.Namespace

全契約タイプ名OperationContext.Current.Host.ImplementedContracts.FirstOrDefault().Value.ContractType.FullName

ます。またOperationContext.Current.Host.Description.ServiceTypeReflectionを使用することができ、それはタイプです。

これが役に立ちます。

+0

'OperationContext.Current.Host'には、ServiceHostに関する情報が含まれています。私はクライアントに関する情報に興味があります。クライアントがチャネル作成に使用した契約。 ServiceHostのImplmentedContractsに私のIServerServiceとIClientServiceがあります。しかし、どの契約がクライアントによって使用されたかの指示はありません。 – toATwork

+0

メッセージインスペクタを実装する必要があるかもしれません。 –

+0

いいえ、それは良くありませんでした。質問の追加情報をご覧ください。 – toATwork

関連する問題