Redis опубликовать/подписаться: посмотрите, какие каналы в настоящее время подписаны на

В настоящее время я заинтересован в том, какие каналы подписываются в приложении Redis pub/sub, которое у меня есть. Когда клиент подключается к нашему серверу, мы регистрируем его на канал, который выглядит так:

user:user_id

Причиной этого является то, что я хочу видеть, кто "онлайн". В настоящее время я слепо отключаю сообщения на канал, не зная, находится ли клиент в сети, так как не критично, что они получают эти типы сообщений.

Чтобы сделать мое приложение более умным, я хотел бы узнать, находится ли клиент в сети или нет, используя API pub/sub, и если они находятся в автономном режиме, кешируйте их сообщения в отдельную очередь redis, которая Я могу нажать на них, когда они вернутся в Интернет.

Это не должно быть на 100% точным, но чем точнее, тем лучше. Я предполагаю, что общий ключ не создается, когда канал подписывается, поэтому я не могу сделать что-то столь же тривиальное, как:

redis-cli keys user*, чтобы найти всех онлайн-пользователей.

Другая стратегия, о которой я подумал, - это просто поддерживать мой собственный Redis Set всякий раз, когда пользователь публикует или удаляет себя из канала (который клиент автоматически обрабатывает, когда он переходит в Интернет и закрывает приложение). Это будет дополнительный уровень сложности, который мне нужно управлять, и я надеюсь, что существует более тривиальный подход к уже имеющимся данным.

Ответ 1

С Redis 2.8 вы можете сделать:

PUBSUB CHANNELS [pattern]

PUBSUB CHANNELS команда имеет сложность O (N), где N - количество активных каналов.

Итак, в вашем случае:

redis-cli PUBSUB CHANNELS user*

даст вам желать лучшего.

Ответ 2

В настоящее время нет команды показывать, какие каналы "существуют" посредством подписки, но есть и "одобренная" проблема и запрос на перенос, который реализует это.

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

Из-за характера этого вызова это не то, что может масштабироваться и, следовательно, является командой "DEBUG".

Однако есть еще несколько способов решить вашу проблему. Если у вас есть основания полагать, что канал может быть подписан, вы можете отправить ему сообщение и посмотреть на результат. Результатом является количество подписчиков, получивших сообщение. Если вы получили 0, вы знаете, что их там нет.

Предполагая, что ваш user_ids является инкрементальным, вам может быть интересно использовать SETBIT, чтобы установить бит 1 или 0 в бит смещения пользователя для отслеживания присутствия. Затем вы можете делать такие классные вещи, как новый BITCOUNT, чтобы узнать, сколько пользователей в сети, и GETBIT, чтобы определить, находится ли конкретный пользователь в сети.

То, как я решил вашу проблему более конкретно в прошлом, - это сигнализировать менеджеру подписки, который я подписал на канал. Менеджер затем "пингирует" канал, отправив пустое сообщение, чтобы подтвердить, что есть подписчик, и изредка пингует канал после этого, чтобы определить, находится ли пользователь в сети. Не идеально, но лучше, чем использование DEBUG CHANNELS в производстве.

Ответ 3

Я не знаю о каком-либо конкретном способе запросить, на какие каналы подписываются, и вы правы, что при этом не создается никакого ключа. Кроме того, я бы не использовал команду KEYS в производстве, так как это действительно команда отладки.

У вас есть правильная идея об использовании набора для добавления пользователя, когда он находится в сети, а затем запросите его с помощью SISMEMBER <set> <user_id>, чтобы определить, следует ли отправлять сообщения им или добавлять их в список Redis для обработки, как только они действительно приходят онлайн.

Вам нужно будет выяснить, когда пользователь выходит из системы, поэтому вы можете удалить их из списка онлайн-пользователей, но я не знаю достаточно о вашей системе, чтобы точно знать, как вы это сделаете.

Если подключенные клиенты имеют возможность отправить сообщение обратно, чтобы сообщить серверу, что сообщение было потреблено, вы можете использовать это, чтобы отслеживать, какие сообщения должны храниться для последующего извлечения.

Cheers, Mike

Ответ 4

Из версии 2.8.0 redis имеет команду pubsub, которая помогла бы в этом случае:

http://redis.io/commands/pubsub

Примечание: в настоящее время состояние 2.8.0 еще не стабильно (RC2)

Ответ 5

Вы можете использовать FastoRedis или FastoNoSql, диалог Pub/Sub.

Паб/Sub диалог

Ответ 6

* PUBSUB NUMSUB [канал-1... канал-N]
Возвращает количество подписчиков (не считая клиентов, подписанных на шаблоны) для указанных каналов. https://redis.io/commands/pubsub