15

我目前有兴趣查看我拥有的 Redis 发布/订阅应用程序中订阅了哪些频道。当客户端连接到我们的服务器时,我们将它们注册到如下所示的通道:

user:user_id

这样做的原因是我希望能够看到谁“在线”。我目前在不知道客户是否在线的情况下盲目地向频道发送消息,因为他们接收这些类型的消息并不重要。

为了使我的应用程序更智能,我希望能够发现客户端是否在线或不使用 pub/sub API,如果他们离线,将他们的消息缓存到一个单独的 redis 队列,我可以推送当他们重新上线时发给他们。

这不一定是 100% 准确,但越准确越好。我假设订阅频道时不会创建通用密钥,所以我不能做一些微不足道的事情:

redis-cli keys user*查找所有在线用户。

我想到的另一个策略是在用户发布或从频道中删除自己时维护我自己的 Redis Set(当他们在线并关闭应用程序时客户端会自动处理)。这将是我需要管理的另一层复杂性,我希望有一种更简单的方法来处理已经可用的数据。

4

5 回答 5

8

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

PUBSUB CHANNELS [pattern]

PUBSUB CHANNELS命令具有 O(N) 复杂度,其中 N 是活动通道的数量。

所以在你的情况下:

redis-cli PUBSUB CHANNELS user*

会给你想要的。

于 2016-08-01T06:04:25.110 回答
3

目前没有命令通过订阅来显示哪些频道“存在”,但存在“已批准”问题和实现此功能的拉取请求。

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

由于这个调用的性质,它不是可以扩展的,因此是一个“DEBUG”命令。

但是,还有其他一些方法可以解决您的问题。如果您有理由相信某个频道可能已被订阅,您可以向其发送消息并查看结果。结果是收到消息的订阅者数量。如果你得到 0,你知道他们不在那里。

假设您user_ids是增量的,您可能有兴趣使用SETBIT将 1 或 0 设置为用户的偏移位来跟踪存在。然后,您可以做一些很酷的事情,比如 newBITCOUNT来查看有多少用户在线,并GETBIT确定特定用户是否在线。

我过去更具体地解决您的问题的方法是向订阅管理器发出我已订阅频道的信号。然后,管理器通过发送空白消息来“ping”频道以确认有订阅者,并在此后偶尔 ping 频道以确定用户是否仍然在线。不理想,但比DEBUG CHANNELS在生产中使用更好。

于 2012-06-09T06:56:54.463 回答
2

从 2.8.0 版本开始,redis 有一个 pubsub 命令,在这种情况下会有所帮助:

http://redis.io/commands/pubsub

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

于 2013-08-17T08:33:23.507 回答
1

我不知道有任何特定方法可以查询正在订阅哪些频道,并且您是正确的,发生这种情况时没有创建任何密钥。另外,无论如何我都不会KEYS在生产中使用该命令,因为它实际上是一个调试命令。

您有一个正确的想法,即在用户在线时使用集合添加用户,然后查询此SISMEMBER <set> <user_id>信息以确定是否应将消息发送给他们或添加到 Redis 列表中以便在他们上线后进行处理。

您需要弄清楚用户何时注销,以便将其从在线用户列表中删除,但我对您的系统了解得不够多,无法确切知道您将如何处理。

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

干杯,迈克

于 2012-06-08T22:48:59.147 回答
0

* PUBSUB NUMSUB [channel-1 ... channel-N]
返回指定频道的订阅者数量(不包括订阅模式的客户端)。 https://redis.io/commands/pubsub

于 2018-01-04T03:12:31.780 回答