【问题标题】:Chatroom functionality with WCF, duplex callbacks vs polling?具有 WCF、双工回调与轮询的聊天室功能?
【发布时间】:2011-12-19 22:02:13
【问题描述】:

我正在使用WCF,并且我正在我的C# 程序中放置一个聊天室设施。所以我需要能够从服务器向客户端发送两个事件的信息 -

  • 当用户连接/断开连接时,我会更新已连接用户的列表并将其发送回所有客户端以在 TextBlock 中显示
  • 当用户发布消息时,我需要服务器将该消息发送给所有客户端

因此,我正在寻求有关实现此功能的最佳方式的建议。我打算使用netTcpBinding 对客户端进行双工回调,但后来我遇到了一些关于如果连接关闭则无法回调客户端的问题。我需要使用 percall 实例来实现可扩展性。我在这个帖子中被告知我不应该让连接保持打开状态,因为它会“显着限制可扩展性” - WCF duplex callbacks, how do I send a message to all clients?

但是,我浏览了 Programming WCF Services 一书,作者似乎指出这不是问题,因为“在两次调用之间,客户端持有一个在代理上没有实际对象的引用电线的末端。这意味着您可以在客户端关闭代理之前很久就处置服务实例占用的昂贵资源'

  1. 那么哪个是正确的,让代理在客户端上保持打开状态可以吗?
  2. 但即使这很好,也会导致另一个问题。如果服务实例在调用之间被销毁,它们如何进行双工回调来更新客户端?关于 percall 实例,Programming WCF Services 的作者说“因为一旦方法返回,对象将被丢弃,因此您不应分离后台线程或将异步调用分派回实例”
  3. 让客户轮询服务以获取更新是否会更好?我会想象这比双工回调效率低得多,客户端最终可能会像使用双工回调一样频繁地轮询服务 50 次以上。但也许没有别的办法?这可以扩展吗?我设想有数百个并发用户。

【问题讨论】:

    标签: c# wcf chatroom


    【解决方案1】:

    由于我告诉您服务器回调无法扩展,因此我可能应该再解释一下。让我从解决您的问题开始:

    1. 如果没有这本书,我只能假设作者指的是基于 http 的传输或仅请求响应,没有回调。回调需要两件事之一 - 服务器需要保持与客户端的开放 TCP 连接(意味着服务器上每个客户端都有资源正在使用中),或者服务器需要能够打开与监听的连接客户端上的端口。由于您使用的是 netTcpBinding,因此您的情况将是前者。 wsDualHttpBinding 是后者的一个示例,但它引入了许多路由和防火墙问题,使其无法在 Internet 上运行(我假设公共 Internet 是您的目标环境,如果不是,请告诉我们)。

    2. 您已经直观地了解了为什么回调需要服务器资源。同样,wsDualHttpBinding 有点不同,因为在这种情况下,服务器实际上是通过新连接回调客户端以发送异步回复。这基本上需要在客户端打开端口并通过任何防火墙,这是普通互联网用户无法预料的。更多内容请点击此处:WSDualHttpBinding for duplex callbacks

    3. 您可以通过几种不同的方式来构建它,但如果您不希望客户端不断地敲击服务器以进行更新,那么这是可以理解的。同样,对于数百个并发用户,您可能仍在一台好的服务器可以使用回调处理的范围内,但我假设您希望拥有一个可以在需要时(或在高峰时间)扩展的系统。我要做的是:

      1. 使用回调代理(我知道,我告诉过你不要)...连接的客户端会创建新的代理,这些代理存储在线程安全的集合中,偶尔会检查是否存在(如果发现会被清除)死了)。

      2. 不要让服务器直接从一个客户端向另一个客户端发布消息,而是让服务器将消息发布到某个Message Queue Middleware。有很多这样的 - MSMQ 在 Windows 中很流行,ActiveMQRabbitMQ 是 FOSS(免费开源软件),Tibco EMS 在大企业中很流行(但可能非常昂贵)。您可能想要使用的是主题,而不是队列(更多关于队列与主题here)。

      3. 在服务器上有一个线程(或多个线程)专门用于从主题中读取消息,并且如果该消息被发送到该服务器上的实时会话,则传递该消息到服务器上的代理。

    这是架构的粗略草图:

    这种架构应该允许您通过简单地添加更多服务器并在它们之间对新连接进行负载平衡来自动扩展。消息队列基础设施将是唯一的限制因素,而且我提到的所有这些都将超出您所见过的任何可能的用例。因为您将使用主题而不是队列,所以每条消息都将被广播到每台服务器 - 您可能需要找出更好的分发消息的方法,例如使用基于哈希的分区。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 2017-06-20
      • 2010-12-26
      相关资源
      最近更新 更多