2012-06-08 1451 views
11

我目前有兴趣了解我拥有的Redis发布/订阅应用中订阅的频道。当客户端连接到我们的服务器,我们将它们注册,看起来像一个通道:Redis发布/订阅:查看目前订阅的频道

user:user_id

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

为了让我的应用程序更加智能化,我希望能够发现客户端是否在线或不使用pub/sub API,如果它们处于脱机状态,则将其消息缓存到单独的redis队列当他们恢复在线时我可以推送给他们。

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

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

我想过的另一种策略是只要用户在频道上发布或删除自己(当客户端在线跳转并关闭应用程序时自动处理)就维护自己的Redis集。这将是我需要管理的一个额外的复杂层面,我希望现有的数据有一个更简单的方法。

回答

1

我不知道任何具体的方式来查询什么渠道正在订阅,并且你是正确的,没有任何密钥创建时发生这种情况。另外,我不会在生产中使用KEYS命令,因为它实际上是一个调试命令。

您有正确的想法:使用一组设备在用户联机时添加用户,然后使用SISMEMBER <set> <user_id>查询此信息以确定消息是应发送给他们还是添加到Redis列表中以供处理联机。

您需要确定用户何时注销,以便您可以将它们从联机用户列表中删除,但我对系统知之甚少,无法确切知道您将如何执行此操作。

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

干杯, 迈克

3

目前用于显示什么渠道“存在”的再订阅方式没有命令,但和“批准”的问题,并实现该拉请求。

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

由于该呼叫的性质,它是不是可以扩展,因此是“调试”命令。

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

假设您的user_ids是增量式的,您可能有兴趣使用SETBIT将1或0设置为用户的偏移位以跟踪存在。然后,您可以执行很酷的操作,例如新的BITCOUNT以查看有多少用户在线,并且可以使用GETBIT来确定特定用户是否在线。

我过去更具体地解决了您的问题的方式是通过发信号通知订阅了一个频道的订阅管理器。管理员然后通过发送空白消息来“ping”该频道,以确认是否存在订户,并且偶尔在该频道上ping通道以确定用户是否仍在线。不理想,但比在生产中使用DEBUG CHANNELS更好。

+0

很棒的建议!我刚才也有同样的需求,并设法通过向频道发布'null'来获得订阅人数来编写它。然后在侦听器中,我检查消息是否为None,如果是,则跳过它。队友的欢呼声! –

1

从2.8.0版本的Redis有一个发布订阅命令,这将有助于在这种情况下:

http://redis.io/commands/pubsub

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

4

作为Redis的2.8的可以这样做:

PUBSUB CHANNELS [pattern] 

PUBSUB CHANNELS command的具有O(N)的复杂性,其中N是活性通道的数量。

所以你的情况:

redis-cli PUBSUB CHANNELS user* 

会给你想要你想要的。