2009-08-04 9 views
1

У меня есть клиентское приложение, сервер и другой клиент, который позволяет называть его третьей стороной. У меня есть интерфейс обратного вызова как часть моего контракта, который реализуется как третьей стороной, так и клиентом.Могу ли я использовать двустороннюю привязку WCF для сообщения ретрансляции?

Третья сторона будет вызывать операцию (метод) сервера, тогда сервер будет инициировать обратный вызов, но вместо вызова обратного вызова третьей стороны он вызовет реализацию обратного вызова клиента.

+1

У меня вопрос не возникает. –

ответ

0

Я думаю, я нашел решение ..

Вот связь. http://msdn.microsoft.com/en-us/magazine/cc163537.aspx

Попробуйте взглянуть на рисунок 6. Вот чего я пытаюсь достичь.

+0

Посмотрите на мой пример ... Я упростил его только с одной операцией, но это тот же шаблон. – kyoryu

0

Из быстрого чтения сервисной документации Microsoft Duplex я не думаю, что он будет делать то, что вы хотите. Для этого может быть какой-то другой умный способ Kung Fu 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

Я не совсем понимаю, что вы действительно спрашиваете здесь .... но я попробую дать несколько советов.

Ретрансляционные сообщения или маршрутизация не очень хорошо поддерживаются в WCF в .NET 3.5 - там есть инфраструктура, но по-прежнему много работы по настройке вручную.

Лучший интро я знаю в этой теме для WCF в .NET 3.5 является статья из двух частей Мишель Леру Бустаманте на журнале MSDN:

Часть 2 имеет раздел о дуплексных маршрутизаторах - это вообще помогает вам в ваших поисках?

WCF в .NET 4.0 обещает предоставить дополнительную поддержку для маршрутизации - будет базовый класс RoutingService, который можно использовать для записи служб маршрутизации, и это позволит настраивать маршрутизацию на основе контента или метаданных - независимо от того, что вам нужно.

. NET 4.0 планируется выпустить через некоторое время в этом году (2009) - надеюсь! Так что, пока это все еще будущее, оно выглядит розовым!

Марк

3

Да, вы можете абсолютно сделать это.

Самый простой способ - реализовать сервис как услугу PerSession и захватить контекст обратного вызова при инициализации/построении. Обычно я добавляю объект службы (который действительно представляет соединение в этой точке) к внутреннему основному объекту.

Затем, когда вы получаете сообщение от клиента, вы можете позвонить любому из объектов службы (а не по контракту) и внутренне перенаправить данные на соответствующий клиент.

Это довольно минимальная реализация концепции без обработки исключений и довольно плохой дизайн (статический класс BAD!). Я не проверял это, но принципы должны соблюдаться, даже если я пропустил пересечение i или пунктир 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); 
    } 
} 
Смежные вопросы