2016-12-06 9 views
0

다음을 고려하십시오.WCF 클라이언트가 여러 계약 (여러 계약)을 연결하는 데 사용한 계약을 서버 측에서 파악하는 방법은 무엇입니까?

하나의 마스터 서버와 마스터 서버와 통신 할 수있는 다른 위치에 여러 서버가 있습니다. 또한 (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이라는 방법으로 확장 할 수는 있지만 저에게는보기 흉한 것처럼 보입니다.

편집는 :

나는 MessageInspector을 구현했다 제안. 그러나 AfterReceiveRequest에 IClientChannel 성공적으로 ICallback

로 주조 할 수 뭐죠 더 이상 호출 스택이 이미 ReliableDuplexSessionChannel 포함되어 있습니다 : 내 서비스 클래스는 콜백이있는 IServerService을 구현하는 경우

> 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] 

이이 뜻 계약서에 정의 된대로 모든 연결 클라이언트는 이중 프록시를 통해 라우팅됩니까? 클라이언트가 사용한 계약 (또는 구현 된 계약)에 상관없이?

답변

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