2011-12-19 129 views
4

我正在使用WCF,我在我的C#计划中添加了一个聊天室设施。所以,我需要能够从服务器向客户端发送信息的两个事件 -聊天室功能与WCF,双工回调与轮询?

  • 当用户连接/断开我更新连接的用户列表,并发送回所有客户端显示在一个TextBlock
  • 当用户发布消息,我需要的服务器来发送邮件给所有客户

所以我要寻找的建议在实施这一点的最好办法。我打算使用netTcpBinding作为客户端的双工回调,但后来我遇到了一些问题,关于在连接关闭时无法回拨客户端。我需要使用percall实例来提高可扩展性。我被告知在这个线程,我不应该离开连接打开,因为它会'大大限制scalibity' - WCF duplex callbacks, how do I send a message to all clients?

但是,我看了一本书编程WCF服务和作者似乎说,这不是一个问题,因为'在两次调用之间,客户端持有一个代理服务器上的引用,该代理服务器没有实际的对象。这意味着,你可以配置昂贵的资源的服务实例占用客户端关闭代理”

  1. 因此,这是正确的,是细保持代理客户端上的长开过吗?
  2. 但即使这很好,它会导致另一个问题。如果服务实例在通话之间被破坏,他们如何执行双工回调来更新客户端?关于percall实例,编程WCF服务的作者说'因为一旦方法返回,对象将被丢弃,你不应该分离后台线程或分派异步调用回实例'
  3. 我会更好的客户端投票更新服务?我会想象这比双工回调的效率低得多,客户最终可能会使用双工回调的次数高达50次以上。但也许没有其他办法?这是可扩展的吗?我设想几百个并发用户。

回答

1

由于我有罪告诉你服务器回调不会扩展,我应该多解释一下。让我解决您的问题开始:

  1. 没有拥有自己的书有问题,我只能假设,笔者要么指基于http传输或仅请求 - 响应,没有回调。回调需要两件事之一 - 或者服务器需要维护与客户端的开放式TCP连接(意味着每个客户端有服务器上正在使用的资源),或者服务器需要能够打开连接以侦听端口在客户端。既然你使用的是netTcpBinding,你的情况就是前者。 wsDualHttpBinding是后者的一个例子,但是它引入了很多路由和防火墙问题,使得它在互联网上无法使用(我假设公共互联网是您的目标环境 - 如果没有,请告诉我们)。

  2. 您已经直观地理解了回调需要服务器资源的原因。同样,wsDualHttpBinding有点不同,因为在这种情况下,服务器实际上是通过新的连接向客户端回叫以发送异步回复。这基本上要求在客户端打开端口,并穿过任何防火墙,这是普通互联网用户所不能期望的。其它更多关于这里:WSDualHttpBinding for duplex callbacks

  3. 您可以构建这几种不同的方式,但如果你不希望不断锤击更新服务器的客户端的开销(和潜在的延迟)这是可以理解的。同样,在几百个并发用户中,您可能仍然处于一个好的服务器可以使用回调处理的范围内,但是我认为您希望有一个系统可以在需要时(或在高峰时间)扩展。我会做的是:

    1. 使用回叫代理(我知道,我告诉你不要)......连接创建新的代理,其存储在一个线程安全的集合,偶尔检查客户端活着(如果发现死亡则清除)。

    2. 而不是让服务器直接从一个客户端发送消息到另一个客户端,让服务器发送消息到一些Message Queue Middleware。有很多这些 - MSMQ是受Windows的欢迎,ActiveMQRabbitMQ是免费开源软件,并且Tibco EMS在大型企业中很受欢迎(但可能非常昂贵)。你可能想要使用的是一个主题,而不是一个队列(更多关于队列与主题here)。

    3. 具有专用于阅读关闭消息的话题服务器上的线程(或多个线程),并如果该消息被发送到实时会话服务器上,传递这一信息转达给服务器上的代理。

这里的建筑的草图:

Queue-backed Chat Architecture

此架构应允许您通过简单地增加更多的服务器和负载平衡它们之间的新连接会自动向外扩展。消息队列基础设施将是唯一的限制因素,我提到的所有这些都将超出您所看到的任何可能的用例。由于您使用的是主题而不是队列,因此每条消息都会广播到每个服务器,您可能需要找出一种更好的分发消息的方式,例如使用基于散列的分区。