Redis 客户端广播问题(在 Socket.IO 的上下文中) [英] Redis clients broadcast problems (in the context of Socket.IO)
问题描述
所以我阅读了一些关于扩展 Socket.IO 的文章.由于各种原因,我不想使用内置的 Socket.IO 缩放机制(主要是它似乎效率低下,因为它向 Redis 发布了更多的东西,然后从我的角度来看是必需的).
So I've read some articles about scaling Socket.IO. For various reasons I don't want to use built-in Socket.IO scaling mechanism (mostly it seems to be inefficient, since it publishes a lot more stuff to Redis then required from my point of view).
所以我想出了一个简单的想法:
So I've came up with this simple idea:
每个 Socket.IO 服务器创建 Redis 发布/订阅/存储客户端,连接到 Redis 并订阅频道.现在,当我想广播数据时,我只需将其发布到 Redis,所有其他 Socket.IO 服务器都会获取它并将其推送给用户.
Each Socket.IO server creates Redis pub/sub/store clients, connects to Redis and subscribes to a channel. Now, when I want to broadcast data I just publish it to Redis and all other Socket.IO servers get it and push it to users.
但是有一个问题(我认为这也是 Socket.IO 内置机制的问题).假设我想知道所有连接用户的数量.至少有两种方法可以做到这一点:
There is a problem, though (which I think is also a problem for Socket.IO built-in mechanism). Let's say I want to know the number of all connected users. There are at least two ways of doing that:
服务器 A 将
give_me_clients
发布到 Redis.然后每个 Socket.IO 服务器计算连接数并发布number_of_clients
.服务器 A 获取这些数据,将其合并并发送给客户端.
Server A publishes
give_me_clients
to Redis. Then each Socket.IO server counts connections and publishesnumber_of_clients
. Server A grabs this data, combines it and sends it to the client.
每当用户连接/断开服务器时,每个服务器都会更新 Redis 中的 number_of_clients_for::ID_HERE
.然后服务器 A 只是获取数据并组合它.可能会更有效率.
Each server updates number_of_clients_for::ID_HERE
in Redis whenever user connects/disconnects to the server. Then Server A just fetches data and combines it. Might be more efficient.
尽管这些解决方案存在问题:
There are problems with these solutions though:
服务器 A 不知道其他服务器.因此他不知道什么时候应该停止监听
number_of_clients
.可以通过让服务器 A 了解其他服务器来解决这个问题:每当服务器连接到 Redis 时,他都会发布new_server
(服务器 A 获取数据并将其存储在内存中).但是,当 Redis - Socket.IO 连接中断时该怎么办?Redis 有没有办法通知客户端其中一个客户端断开连接?
Server A is not aware of other servers. Therefore he does not know when he should stop listening to
number_of_clients
. One could fix it with making Server A aware of other servers: whenever a server connects to Redis he publishesnew_server
(Server A grabs the data and stores it in memory). But what to do, when Redis - Socket.IO connection breaks? Is there a way for Redis to notify clients that one of the client disconnected?
其实和上面一样.当 Socket.IO 服务器崩溃时,如何清除 number_of_clients
数据?
Actually the same as above. When a Socket.IO server crashes how to clear number_of_clients
data?
所以真正的问题是:Redis 能否通知(发布到 chanel)客户端与其中之一的连接刚刚结束??
So the real question is: can Redis notify (publish to chanel) clients that the connection with one of them has just ended??
推荐答案
经过大量测试,Redis 似乎没有这样的功能.我还发现,扩展 Socket.IO 真的很痛苦.
After a lot of testing it seems, that Redis does not have such functionality. Also I've found out, that scaling Socket.IO is really a pain.
所以我已经从 Socket.IO 切换到 WS(请参阅此链接).它是低级别的(但非常适合我使用)并且它只支持 WebSockets(在所有主要版本中).但话说回来,我只想支持 WebSockets 和 FlashSocket(我必须手动实现,但这很好).
So I've switched from Socket.IO to WS (see this link). It is low level (but perfect for my use) and it only supports WebSockets (in all major versions). But then again I only want to support WebSockets and FlashSocket (which I have to imlement manually, but that's fine).
优点是我可以轻松地使用此类服务器创建集群.HAProxy 几乎是开箱即用的(一些小的调整).服务器可以轻松地在本地网络上进行通信(如果集群很大,则使用 UDP 或中央 TCP 服务器).
The advantage is that I can easily create cluster with such servers. HAProxy works with such servers almost out of the box (some minor tuning). Servers can easily communicate on a local net (with UDP or central TCP server if the cluster is big).
缺点是必须手动实现一些很酷的功能,例如心跳、广播、房间等.您还需要长轮询回退,但对我来说这很好.恕我直言,缩放仍然更重要.
The disadvantage is that one have to manually implement some cool features like heartbeats, broadcasting, rooms, etc. Also you want have long-polling fallback, but that's fine in my case. Scaling is still more important, imho.
这篇关于Redis 客户端广播问题(在 Socket.IO 的上下文中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!