Redis发布/订阅:查看当前订阅的频道

15
我目前有一个Redis pub/sub应用程序,我想知道订阅了哪些频道。当客户端连接到我们的服务器时,我们会将他们注册到一个看起来像这样的频道: user:user_id 之所以这样做是因为我想知道谁“在线”。目前,我不知道客户端是否在线就盲目地向频道发送消息,因为他们接收这些类型的消息并不是必要的。
为了让我的应用程序更加智能,我希望能够使用pub/sub API发现客户端是否在线,如果他们离线了,就将他们的消息缓存到一个单独的redis队列中,当他们重新上线时可以将它们推送给他们。
这不一定要100%准确,但越准确越好。我假设当订阅一个频道时不会创建通用密钥,因此我无法像这样简单地执行操作: redis-cli keys user* 来查找所有在线用户。
我考虑过的另一种策略就是维护自己的Redis Set,每当一个用户发布或删除自己的频道(当他们在线和关闭应用程序时,客户端会自动处理)时,都要更新Set。这将是我需要管理的额外复杂性层面,我希望有一种更简单的方法利用已有的数据。
5个回答

11

从Redis 2.8版本开始,您可以执行以下操作:

PUBSUB CHANNELS [pattern]

PUBSUB CHANNELS 命令 的复杂度为 O(N),其中 N 为活动频道数。

所以在您的情况下:

redis-cli PUBSUB CHANNELS user*

会给你想要的东西。


这个命令在 StackExchange.Redis.NET Redis驱动程序)中可用吗? - Bercovici Adrian

3

目前还没有显示已订阅频道的命令,但是有一个“已批准”的问题和一个拉请求实现了这个功能。

https://github.com/antirez/redis/issues/221
https://github.com/antirez/redis/pull/412

由于此调用的性质,它不是可扩展的,因此是一个“DEBUG”命令。
然而,还有其他几种解决问题的方法。如果您有理由相信某个频道可能已经订阅了,您可以向其发送一条消息并查看结果。结果是收到消息的订阅者数量。如果您得到了0,则知道他们不存在。
假设您的user_ids是递增的,您可能会对使用SETBIT来设置用户偏移位的1或0以跟踪存在状态感兴趣。然后,您可以执行像新的BITCOUNT一样酷的操作来查看有多少用户在线,并使用GETBIT确定特定用户是否在线。
我过去更具体地解决了您的问题,方法是向订阅管理器发出信号,表明我已经订阅了一个频道。然后,管理器通过发送空白消息来确认是否有订阅者,并在此后偶尔ping该频道以确定用户是否仍然在线。虽然不理想,但比在生产中使用DEBUG CHANNELS要好。

太好了!我刚有同样的需求,通过发布'null'到通道来获取订阅者数量成功地解决了它。然后在侦听器中,如果消息为空,就跳过它。兄弟干杯! - Gabriel Samfira

2
从2.8.0版本开始,Redis有一个pubsub命令可以在这种情况下帮助:

http://redis.io/commands/pubsub

备注:目前2.8.0的状态尚不稳定(RC2)。

1

我不知道有什么特定的方法来查询正在订阅哪些频道,你说得对,当这种情况发生时也没有任何键被创建。此外,我不会在生产中使用KEYS命令,因为它实际上是一个调试命令。

您对使用集合添加用户在线时的想法是正确的,然后使用SISMEMBER <set> <user_id>查询以确定是否应将消息发送给他们或将其添加到Redis列表以供稍后处理。

您需要找出用户何时注销,以便将其从在线用户列表中删除,但我不了解您的系统足够了解您将如何进行操作。

如果连接的客户端有能力发送消息回来通知服务器消息已被消耗,您可以使用此功能来跟踪应存储哪些消息以供稍后检索。

祝好, Mike


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接