Redis 客户端广播问题(在 Socket.IO 的上下文中)

标签 redis socket.io scalability publish-subscribe disconnect

所以我读了一些关于扩展 Socket.IO 的文章。由于各种原因,我不想使用内置的 Socket.IO 扩展机制(主要是它似乎效率低下,因为它向 Redis 发布了比我认为需要的更多内容)。

所以我想出了这个简单的想法:

每个 Socket.IO 服务器都会创建 Redis 发布/订阅/存储客户端、连接到 Redis 并订阅 channel 。现在,当我想要广播数据时,我只需将其发布到 Redis,所有其他 Socket.IO 服务器都会获取它并将其推送给用户。

但是有一个问题(我认为这也是 Socket.IO 内置机制的问题)。假设我想知道所有已连接用户的数量。至少有两种方法可以做到这一点:

  1. 服务器 A 将 give_me_clients 发布到 Redis。然后每个 Socket.IO 服务器计算连接数并发布 number_of_clients。服务器 A 获取此数据,将其组合并将其发送到客户端。

  2. 每当用户连接/断开与服务器的连接时,每个服务器都会更新 Redis 中的number_of_clients_for::ID_HERE。然后服务器 A 只是获取数据并组合它。可能会更有效率。

但是这些解决方案存在问题:

  1. 服务器 A 不知道其他服务器。因此,他不知道什么时候应该停止监听 number_of_clients。人们可以通过让服务器 A 知道其他服务器来解决这个问题:每当服务器连接到 Redis 时,他就会发布 new_server (服务器 A 获取数据并将其存储在内存中)。但是,当 Redis - Socket.IO 连接中断时该怎么办? Redis 有没有办法通知客户端其中一个客户端已断开连接?

  2. 其实和上面一样。当 Socket.IO 服务器崩溃时如何清除 number_of_clients 数据?

所以真正的问题是:Redis 能否通知(发布到chanel)客户端与其中一个客户端的连接刚刚结束?

最佳答案

经过大量测试,Redis 似乎没有这样的功能。我还发现,扩展 Socket.IO 确实很痛苦。

所以我已经从 Socket.IO 切换到 WS(请参阅 this link )。它的级别较低(但非常适合我的使用),并且仅支持 WebSockets(在所有主要版本中)。但话又说回来,我只想支持 WebSockets 和 FlashSocket(我必须手动实现,但这很好)。

优点是我可以轻松地使用此类服务​​器创建集群。 HAProxy 几乎可以开箱即用地与此类服务器配合使用(进行一些小的调整)。服务器可以轻松地在本地网络上进行通信(如果集群很大,则使用 UDP 或中央 TCP 服务器)。

缺点是必须手动实现一些很酷的功能,如心跳、广播、房间等。您还希望有长轮询后备,但这对我来说没问题。恕我直言,规模化仍然更重要。

关于Redis 客户端广播问题(在 Socket.IO 的上下文中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11115863/

相关文章:

database - 在NoSQL和RDBMS中扩展?

repository - 在常见的 x86 硬件上水平扩展存储库

php - 使用redis作为具有许多键但服务器上没有太多内存的数据库(php)

redis - Redis如何根据两个不同的sorted set进行排序呢?

mysql - 使用 Node.js 和 mySQL

python - Tornadio2 + Socket.io 负载测试

ios - objc项目中使用Socket.IO-Client-Swift的问题

Mysql 一个大数据库或多个小表

asp.net - 使用负载均衡器时摆脱 redis 作为背板

javascript - Node.JS 对象原型(prototype)在 Redis 中只能是一个 Object 或 null