2009-08-04 3 views
1

나는 클라이언트 응용 프로그램, 서버 및 다른 클라이언트를 가지고 있으며 타사라고 부를 수 있습니다. 제 3 자와 클라이언트가 모두 구현 한 계약의 일부로 콜백 인터페이스가 있습니다.릴레이 메시지에 WCF 이중 바인딩을 사용할 수 있습니까?

제 3자가 서버 작업 (메서드)을 호출하면 서버가 콜백을 트리거하지만 제 3 자의 콜백을 호출하는 대신 클라이언트의 콜백 구현을 호출합니다.

+1

여기에 질문이 없습니다. –

답변

0

Microsoft Duplex 서비스 설명서를 빠르게 읽었 으면 내가 원하는대로 할 수 있다고 생각하지 않습니다. 거기에 다른 영리한 쿵푸 WCF 방식으로 할 수 있지만 내 경우에는 실제 서비스와 동일한 계약을 구현하고 클라이언트에받은 요청을 보낸 서버에 대한 "PassThruService"를 만들었습니다.

이것은 내 코드의 일부분으로 설명됩니다.

private const int OPERATION_TIMEOUT = 5000; 
private MyServiceClient m_client = new MyServiceClient(); 

public bool IsAlive() { 
    try { 
     logger.Debug("PassThruService IsAlive."); 

     bool isAlive = false; 
     ManualResetEvent isAliveMRE = new ManualResetEvent(false); 

     m_client.IsAliveComplete += (s, a) => { isAlive = a.Result; isAliveMRE.Set(); }; 
     m_client.IsAliveAsync(); 

     if (isAliveMRE.WaitOne(OPERATION_TIMEOUT)) { 
      return isAlive; 
     } 
     else { 
      throw new TimeoutException(); 
     } 
    } 
    catch (Exception excp) { 
     logger.Error("Exception PassThruService IsAlive. " + excp.Message); 
     throw; 
    } 
0

나는 완전히 당신이 정말로 여기 요구하는지 표시되지 않습니다 ....하지만 어쨌든 몇 가지 팁을 제공하려고합니다.

릴레이 메시지 또는 라우팅은 .NET 3.5의 WCF에서 잘 지원되지 않습니다. 인프라는 있지만 거기에 수동으로 설정하는 작업은 여전히 ​​많습니다.

부 :

내가 .NET 3.5에서 WCF에 대한이 주제에 알 수있는 가장 좋은 소개는 MSDN 잡지에 미셸 레녹스 부스타에 의해 두 부분으로 기사입니다 2는 듀플렉스 라우터에 관한 섹션을 가지고 있습니다.

.NET 4.0의 WCF는 라우팅에 대한 추가 지원을 약속합니다. RoutingService 기본 클래스는 라우팅 서비스를 작성하는 데 활용 될 수 있으며 구성 가능한 콘텐츠 기반 또는 메타 데이터 기반 라우팅을 허용합니다. 당신이 필요하다는 것입니다.

.NET 4.0은 올해 하반기에 출시 될 예정입니다. (2009) - 잘하면! 그럼에도 불구하고 아직 미래가 밝지 만 장미 빛이 나옵니다.

마크

3

예, 물론 그렇게 할 수 있습니다.

가장 쉬운 방법은 서비스를 PerSession 서비스로 구현하고 초기화/구성시 콜백 컨텍스트를 캡처하는 것입니다. 일반적으로 서비스 객체 (실제로 그 시점에서 연결을 나타냄)를 내부 핵심 객체에 추가합니다.

그런 다음 클라이언트에서 메시지를 받으면 계약이 아닌 서비스 개체를 호출하고 내부적으로 관련 클라이언트에 데이터를 전달할 수 있습니다.

이것은 예외 처리를하지 않고도 개념을 매우 최소한으로 구현 한 것이며 꽤 나쁜 설계 (정적 클래스 BAD!)입니다. 나는 이것을 시험하지는 않았지만, 나는 횡단하거나 t 점을 놓치더라도 원리는 유지되어야한다. 또한이 예에서는 모두 클라이언트로 통화를 전달하지만 개별 클라이언트를 선택하는 것은 동일한 기본 패턴을 따릅니다.여기

.. 내가 해결책을 찾은 것 같아요 싱글 서비스와 함께이 작업을 수행하려고

더 어려울 것입니다, 그리고 통화 당 서비스는 분명히 작동하지 않습니다 :)

[ServiceContract(CallbackContract = typeof(ICallback))] 
public interface IContract 
{ 
    [OperationContract(IsOneWay = true)] 
    void SendTheData(string s); 
} 

public interface ICallback 
{ 
    [OperationContract(IsOneWay = true)] 
    void ForwardTheData(string s); 
} 

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.PerSession)] 
public class ServiceConnection : IContract 
{ 
    private ICallback m_callback; 

    public ServiceConnection() 
    { 
     m_callback = OperationContext.Current.GetCallbackChannel<ICallback>(); 
     ServiceCore.Add(this); 
    } 

    public void SendTheData(string s) 
    { 
     ServiceCore.DataArrived(s); 
    } 

    public void SendToClient(string s) 
    { 
     m_callback.ForwardTheData(s); 
    } 
} 

static public class ServiceCore 
{ 
    static private List<ServiceConnection> m_connections = new List<ServiceConnection>(); 


    public static void DataArrived(string s) 
    { 
     foreach(ServiceConnection conn in m_connections) 
     { 
      conn.SendTheData(s); 
     } 
    } 

    public static void Add(ServiceConnection connection) 
    { 
     m_connections.Add(connection); 
    } 
} 
관련 문제