分布式系统中客户端之间的websocket通信

时间:2016-07-12 20:51:33

标签: sockets google-app-engine chat distributed-system instant-messaging

我正在尝试构建即时消息应用。客户端不仅会发送消息,还会发送音频。我决定使用websocket连接与客户进行通信。它很快并允许发送二进制数据。

 主要想法是从 client1 消息接收并通知 client2 。但事情就是这样。我的应用程序将在GAE上运行。如果在 server1 client2 上打开 client1 的套接字,该怎么办?在 server2 上打开。这些服务器并不了解彼此的客户。

我有一个想法如何解决它,但我确信这是糟糕的方式。我将在服务器之间使用某种通信(例如JMS或在服务器之间打开另一个websocket连接,现在并不重要。)
 但它肯定会导致灾难。我甚至无法想象这些服务器会互相通话的频率。对于每封邮件 server1 应通知 server2 server2 应通知 client2 。但是当 serverN 发挥作用时情况变得更糟。

另一种我认为可行的方法是Firebase。但它将邮件大小限制为4KB。所以我无法通过它发送音频。作为一种解决方案,我可以通知客户有关新音频的信息,然后他会去我的服务器。

希望我清楚地解释了这个问题。有谁知道如何解决它?或者也许有其他方法来构建这样的应用程序?

2 个答案:

答案 0 :(得分:1)

如果要构建消息传递集群并期望通信客户端连接到服务器的不同实例,则服务器 - 服务器通信是不可避免的。通常这不是问题。

  • 首先,如果您不使用任何负载平衡,您的客户端将平均50%的时间连接到同一服务器(如果是2台服务器)。
  • 其次,数据中心内链接在所有已知的公共云中都是快速且免费的。
  • 第三,你经常可以在前端做一些聪明的事情,以确保两个可能通信客户端连接到同一台服务器。例如,使用DNS负载平衡将来自同一国家/地区的所有客户端指向同一服务器。

问题的第二部分是关于传递大型媒体文件。将它发送到带外存储在服务器上并且只传递对它的引用是一种常见的最佳实践。与评论中建议的人一样,将音频保存在服务器上,只需发送“音频可用,从此处获取...”等消息。您无需为此轮询服务器。只需在接收客户端请求它时获取一次。

一般来说,您似乎正在尝试重新发明轮子。只需使用现成的东西。

答案 1 :(得分:0)

  1. 让所有客户端都连接到多台服务器,并且每台服务器都保留该元数据
  2. 像Zookeeper这样的集中式系统会存储活动服务器的详细信息
  3. 当客户端c1向客户端c2发送消息时:

    • 该消息已由服务器接收(例如s1,我们可以添加自动均衡器来分配传入的请求
    • s1将向所有其他服务器广播此信息,以获取客户端c2连接到哪个服务器的 OR ,这是使用一致哈希的一种更好的方法,该方法决定了客户端可以连接到哪个服务器,并采用这种方式不需要广播消息
    • 相应的服务器对服务器s1(例如s2)的响应
    • 现在 s1 发送消息 m s2 ,并将服务器 s2 发送到客户端 c2

上述方法的缺点:

  1. 每个服务器将与n-1个服务器建立连接,从而创建网状拓扑

  2. 集中式系统(zookeeper)成为单点故障(可解决)

Whatsapp,G-Talk等应用程序使用XMPP和TCP / IP。