我可以使用WCF双工绑定来中继消息吗?

时间:2009-08-04 12:10:02

标签: c# wcf binding callback duplex

我有一个客户端应用程序,一个服务器和另一个客户端,我们称之为第三方。我有一个回调接口作为我的合同的一部分,由第三方和客户实现。

第三方将调用服务器操作(方法),然后服务器将触发回调,但它不会调用第三方的回调,而是调用客户端的回调实现。

4 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分: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;
    }

答案 2 :(得分:0)

我没有完全看到你在这里问的是什么......但我会尝试提供一些提示。

在.NET 3.5中的WCF中不能很好地支持中继消息或路由 - 基础设施就在那里,但是手动设置它仍然需要做很多工作。

我在.NET 3.5中为WCF所知的最佳介绍是Michele Leroux Bustamante在MSDN杂志上的一篇由两部分组成的文章:

第2部分有关于双工路由器的部分 - 这对你的任务有帮助吗?

.NET 4.0中的WCF承诺为路由提供额外支持 - 将有一个RoutingService基类可用于编写路由服务,它将允许基于可配置,内容或元数据的路由 - 无论你需要什么。

.NET 4.0计划于今年晚些时候(2009年)发布 - 希望如此!所以虽然这仍然是未来,但它看起来很美好!

马克

答案 3 :(得分:0)

我想我找到了解决方案..

这是链接。 http://msdn.microsoft.com/en-us/magazine/cc163537.aspx

试着看看图6.这就是我想要实现的目标。