C# 集群环境中的WCF双工通信

C# 集群环境中的WCF双工通信,c#,wcf,silverlight,web-services,duplex,C#,Wcf,Silverlight,Web Services,Duplex,所以我在看人们为双工通信创建的示例,即当由IIS托管并通过Silverlight连接时。有很多这样的例子(),但都使用相同的范例: 用户A连接到服务器A,它会将其放入内存列表中,以接收将来的更新。 用户B连接到服务器A,它通知列表中的所有用户有人“登录” 。。。但是,当 用户C连接到服务器C,服务器C的内存中列表不包含用户A或B 问题是,我希望在集群(web场)环境中实现这一点。这使事情变得复杂,因为我无法验证哪台机器将最终执行wcf调用,因此很难将任何消息转发给所有其他用户 我能想到的最好的方

所以我在看人们为双工通信创建的示例,即当由IIS托管并通过Silverlight连接时。有很多这样的例子(),但都使用相同的范例:

用户A连接到服务器A,它会将其放入内存列表中,以接收将来的更新。
用户B连接到服务器A,它通知列表中的所有用户有人“登录”

。。。但是,当

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

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

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

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

我错过了什么

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


到目前为止,我们只需在db中轮询表以查找更改。仍然像一个丑陋的婴儿。

您可以使用“粘性IP”配置您的web服务器场

这意味着当客户机连接到web场时,他将被路由到一台机器。来自该客户端的所有以下请求都将转到服务器场上的同一台机器。 这有点像您在问题中描述的路由服务

编辑

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

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

编辑2

在需要同时与所有用户通信的情况下,调用不需要一直到数据库。这可以缓存在WCF服务级别的内存中,其他客户端将从内存中获取,从而提供更好的性能和更少的数据库负载

编辑3

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

  • 使用Azure服务总线,每个客户端与云中的一个端点对话,该端点转换为直接通信
  • 使用silverlight删除,使用可以公开WCF服务端点的客户端。当客户端启动时,它向服务器注册端点。然后,每个客户机都可以询问在线的服务器,并直接向客户机发送消息

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


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

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

使用Memcached或MSMQ

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


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

您的解决方案提供商是否将MS SQL用于数据库服务器?若您拥有MS SQL数据库的完全权限,则可以实现T-SQL触发器。您可以编写一个触发器,在数据库CRUD操作发生时执行代码。使用当前版本的MS SQL,您甚至可以执行托管(C#/VB#)代码

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

这是我的建议<