如何回调客户端并公开具有实例上下文的新通道
我正在使用 netTcpBinding 制作 WCF 服务,该服务有一个主大厅,其中有多个客户端可以进入的聊天室。 Lobby 类将 ILobby 实现为服务契约。
当客户端希望进入一个房间时,我想回调客户端,公开一个新的 Channel,其中包含他刚刚进入的房间的 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 类中并自己处理所有内容?
I'm making a WCF service with netTcpBinding which has a main lobby with multiple chatrooms which the clients can enter. The Lobby class implements ILobby as the service contract.
When a client wishes to enter a room I want to callback the client exposing a new Channel containing the InstanceContext for the room he just entered but after much searching I am doubting that this is possible.
For example on the Service side I might have
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;
}
}
On the client side callback method I want
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
}
Is this possible? What's the best practice for spawning new classes with their own contracts on the service side? Or do I just have to bundle everything into one massive MyService class and handle everything myself?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不能将实例上下文作为参数传递给任何操作合约。这是没有意义的,因为该上下文具有本地范围。它被称为“实例上下文”=它是当前服务实例的上下文。在双工场景中,客户端和服务器都有自己的服务:
的服务 服务器的服务实例上下文仅在服务器上有意义。目前尚不清楚您想要实现什么(除了非常复杂的架构)。
IInstanceContextProvider
以及您自己的IInstanceProvider
(取决于您想要实现的目标),将它们包装在行为中并将它们添加到服务中。这将使会话处理和正确实例释放的整体复杂性置于您的控制之下(显然它有其优点和缺点)。但真的有必要吗?当我查看您的代码时,我发现一项服务和一个代理就足够了。另外,您的
JoinRoom
操作根本不需要使用回调,它可以只是请求响应方法。You cannot pass instance context as parameter to any operation contract. It doesn't make sense because that context has local scope. It is called "instance context" = it is context of current service instance. In duplex scenario both client and server has its own service:
Server's service instance context has meaning only on the server. It is not clear what you are trying to achieve (except very complex architecture).
IInstanceContextProvider
and perhaps also your ownIInstanceProvider
(depending on what you want to achieve), wrap them in behavior and add them to the service. That will put whole complexity of session handling and correct instance releasing under your control (it obviously has its pros and cons).But is it really needed? When I look at your code I see that one service and one proxy is enough. Also your
JoinRoom
operation doesn't need to use callback at all, it can be just request response method.