如何回调客户端并使用实例上下文公开新的Channel

时间:2011-09-15 03:22:25

标签: wcf nettcpbinding wcf-callbacks

我正在使用netTcpBinding创建一个WCF服务,它有一个主要大厅,有多个聊天室,客户可以输入。 Lobby类将ILobby作为服务合同实现。

当客户希望进入一个房间时,我想回调客户端,为他刚刚输入的房间展示一个包含InstanceContext的新频道,但经过大量搜索后,我怀疑这是可能的。

例如,在服务方面我可能有

class Lobby : ILobby
{
    Dictionary<string, Chatroom> rooms;

    public void JoinRoom(string roomname)
    {
        if (rooms[roomname].TryEnter()) {}
    }
}

class ChatRoom : IChatRoom
{
    public bool TryEnter(string username)
    {
        ILobbyCallback callback =
            OperationContext.Current.GetCallbackChannel<ILobbyCallback>();
        // How do I do this next bit?
        callback.JoinedRoom(pass some instance context here);
        return true;
    }
}

在我想要的客户端回调方法

public void JoinedRoom(InstanceContext for the room on the service side)
{
    // Create a new WCF proxy using above InstanceContext
    // Create a WPF UI for the new room passing the proxy so it can communicate
    // with the room class directly without going via the root service
}

这可能吗?在服务方面使用自己的合同生成新类的最佳实践是什么?或者我只需将所有内容捆绑到一个庞大的MyService类中并自己处理所有内容?

1 个答案:

答案 0 :(得分:1)

您无法将实例上下文作为参数传递给任何操作合同。它没有意义,因为该上下文具有局部范围。它被称为“实例上下文”=它是当前服务实例的上下文。在双工方案中,客户端和服务器都有自己的服务:

  • 客户端通过其代理
  • 调用服务器的服务
  • 服务器通过收到的回叫频道调用客户端'服务

服务器的服务实例上下文仅在服务器上有意义。目前尚不清楚你想要实现的目标(除了非常复杂的架构)。

  • 如果你想在客户端上共享上下文,你可以尝试传递用于你创建的第一个代理的实例上下文 - 我不确定它是否可行但你可以试试
  • 如果您想在多个代理之间共享服务实例上下文,您必须开发自己的IInstanceContextProvider,也可能是您自己的IInstanceProvider(取决于您想要实现的目标),将它们包装在行为中并添加他们去服务。这将使会话处理的整个复杂性和正确的实例发布在您的控制之下(显然有其优点和缺点)。

但它真的需要吗?当我查看您的代码时,我发现一个服务和一个代理就足够了。此外,您的JoinRoom操作根本不需要使用回调,它可以只是请求响应方法。