代码之家  ›  专栏  ›  技术社区  ›  JustLoren

集群环境中的WCF双工通信

  •  3
  • JustLoren  · 技术社区  · 15 年前

    所以我在看人们为双工通信创建的示例,即当由IIS托管并通过Silverlight连接时。有很多这样的例子( this MSDN article is great ),但是 全部的

    用户A连接到服务器A,它将他放入内存列表中以接收将来的更新。

    ... 但是当

    用户C连接到服务器C,服务器C的内存列表中不包含用户A或B。

    问题是,我希望在集群(web场)环境中实现这一点。这使事情变得复杂,因为我无法验证哪台机器将最终执行wcf调用,因此很难将任何消息转发给所有其他用户。

    我能想到的最佳方案是让客户机连接到某种路由服务,该服务接收传入的请求并将客户机转发到特定的机器。当然,这样我就失去了web场的好处,因为只有一台机器可以有效地处理所有传入的请求。

    一个不太有效的解决方案是让服务不断地轮询某些内容(文件服务器上的文件或数据库中的表)以查找更改。一旦出现变化,就把它们推给客户。这看起来像一个非常丑陋的婴儿,tho。

    我错过了什么?

    更新-路由系统不可能满足我的需要。我的托管公司不允许我通过IP直接连接到服务器场上的特定计算机。我只能连接到通用的负载平衡器前端,因此不能保证我的用户将在同一台服务器上结束。

    到目前为止,我们只在db中轮询表以查找更改。看起来还是个丑陋的婴儿。

    8 回复  |  直到 15 年前
        1
  •  2
  •   jrista    15 年前

    假设除了可以在每台服务器上安装什么以外,您对环境的控制为零(即没有MSMQ、没有ESB等),那么我将研究如何使用WCF在服务器之间进行通信。简单的问题似乎是,内存中的列表需要在两个服务器之间保持同步,并且每当列表的内容发生更改时,都需要通知两个服务器的用户。

    使用服务器托管和使用的内部WCF服务,您可以使用简单的fire-and-forget消息来保持列表同步。想象一下下面的场景:

      1. 将“用户A”添加到联机用户列表
        1. 使服务器B通知所有用户用户登录
      2. 通知服务器A上的所有用户用户登录
      1. 将“用户B”添加到联机用户列表
      2. 将消息发送到服务器A,通知其添加了“用户B”
        1. 使服务器A通知所有用户用户登录
    1. “用户A”从服务器A注销
      1. 从联机用户列表中删除“用户A”
        1. 使服务器B从其联机用户列表中删除“用户A”
        2. 使服务器B通知所有用户用户注销
    2. 定期让服务器A和服务器B同步它们的列表

        2
  •  1
  •   Jeff    15 年前

    假设您不需要实时类型的通知,一种典型的方法是使用后端会话数据库或专用会话服务器,以便所有集群计算机都能看到您当前登录的所有用户。然后您可以编写一个轮询服务来发送更改通知,或者根据您的需求编写更高级的服务。

    在您的示例中,您可以将“内存中”用户列表移动到共享内存服务器或共享数据库。当然,您可以实现某种类型的集群更新通知以发送到所有计算机,但其复杂性可能远远超出您的需要。

        3
  •  1
  •   Yuliy    15 年前

    服务器之间可以直接通信吗?如果是这样,您可能希望设置只有服务器场中的其他服务器才能连接的专用终结点。然后,当服务器C收到一条消息时,它向服务器a发送一条消息,通知它这个事实,然后服务器a可以将这个消息转发给它的客户机。

        4
  •  1
  •   Doanair    15 年前

    有了Memcached,您可以将它作为所有需要广播的项目的单一真相点。因此,当您获得客户端登录时,您会将一些简单的数据转储到Memcached中。它通知另一个服务器并更新另一个服务器的列表。然后,在发布信息时,查询Memcached。

    使用MSMQ,将登录信息推送到队列,然后在两台服务器上实现侦听器,从队列中读取并更新内存中的“可发布”信息列表。这样,两个服务器都可以随时了解需要发布的数据。

        5
  •  1
  •   Jeff    15 年前

    这个解决方案非常复杂,但也是可能的。我将为您的集群使用一个中央mssql,并编写一些T-SQL触发器代码。当您关心的记录被修改/etc时,我会让SQL服务器向集群中的其他服务器发送特殊的httpweb请求消息(假设集群中的一个服务器可以任意地与其他/所有集群服务器通信),让它们知道任何更改。然后,每个服务器都可以使用全局应用程序缓存向服务器上的每个会话广播更改。

    -杰夫

        6
  •  1
  •   JontyMC    15 年前

    看起来您需要使用对等网络(netPeerTcpBinding)。我不确定你的托管环境是否支持这个。

    http://msdn.microsoft.com/en-us/library/cc297274.aspx

        7
  •  0
  •   Shiraz Bhaiji    15 年前

    这有点像您在问题中描述的路由服务。

    在silverlight客户机询问web服务器“我有什么新东西吗”的情况下,实现一个轮询系统可能是最简单的,该请求将包含客户机最后一次询问的时间。新事物的列表将存储在一个数据库表中。所以你点击哪个网络服务器没有问题。

    另外,您需要注意silverlightwcf中的限制,如果我理解正确的话,它并没有实现所有的WCF。

    编辑2

    只要您使用的是silverlight客户机,客户机就很难彼此直接通信。有两种可能,尽管它们需要额外的工作/成本:

    • 使用silverlight删除,使用可以公开WCF服务端点的客户端。当客户端启动时,它向服务器注册端点。然后,每个客户机都可以询问在线的服务器,并直接向客户机发送消息。
        8
  •  0
  •   Jacky Jacky    15 年前

    MS的velocity项目对您来说可能比数据库后端更快; 它的API非常简单,并且与.NET的其他部分保持一致。