2012-06-08 15 views
11

Actualmente estoy interesado en ver qué canales están suscritos a un Redis pub/sub Aplicación tengo. Cuando un cliente se conecta a nuestro servidor, que se registren a un canal que se parece a:Redis publicación/suscripción: ver qué canales están suscritos actualmente a

user:user_id

La razón de esto es que quiero ser capaz de ver quién está "en línea". Actualmente, disparo ciegamente los mensajes a un canal sin saber si un cliente está en línea, ya que no es crítico que reciban este tipo de mensajes.

En un esfuerzo por hacer que mi aplicación sea más inteligente, me gustaría poder descubrir si un cliente está en línea o no utilizando la API pub/sub, y si están desconectados, almacenar sus mensajes en caché en una cola redis separada que puedo presionarles cuando vuelven a estar en línea.

Esto no tiene por qué ser fiable al 100%, pero cuanto más precisa sea, mejor. Supongo que una clave genérica no se crea cuando se suscribe un canal, por lo que no puedo hacer algo tan trivial como:

redis-cli keys user* para encontrar a todos los usuarios en línea.

La otra estrategia en la que he pensado es simplemente mantener mi propio Redis Set cada vez que un usuario publica o se elimina de un canal (que el cliente maneja automáticamente cuando salta en línea y cierra la aplicación). Esa sería una capa adicional de complejidad que necesito administrar y espero que haya un enfoque más trivial con los datos que ya están disponibles.

Respuesta

1

estoy al tanto de ninguna manera específica para consultar qué canales están siendo suscritas y Tiene razón en que no hay ninguna tecla crea cuando esto sucede. Además, no utilizaría el comando KEYS en producción de todos modos, ya que es realmente un comando de depuración.

Tiene la idea correcta de utilizar un conjunto para agregar al usuario cuando están en línea, y luego consultar esto con SISMEMBER <set> <user_id> para determinar si los mensajes deben ser enviados o agregados a una lista de Redis para su procesamiento una vez que lo hacen entrar en línea.

Tendrá que averiguar cuándo un usuario cierra sesión para que pueda eliminarlos de la lista de usuarios en línea, pero no sé lo suficiente sobre su sistema para saber exactamente cómo hacerlo.

Si los clientes conectados tienen la capacidad de enviar un mensaje de regreso para informar al servidor que el mensaje se consumió, puede usar esto para mantener un registro de los mensajes que se deben almacenar para su posterior recuperación.

Saludos, Mike

3

Actualmente no existe una orden para mostrar lo que "existen" canales a modo de ser suscrito, pero existe y "aprobado" tema y una solicitud de extracción que implementa esto.

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

Debido a la naturaleza de esta llamada, no es algo que puede escalar, y es por lo tanto un comando "debug".

Hay algunas otras maneras de resolver su problema, sin embargo. Si tiene motivos para creer que un canal puede estar suscrito, puede enviarle un mensaje y observar el resultado. El resultado es la cantidad de suscriptores que recibieron el mensaje. Si tienes 0, sabes que no están allí.

Suponiendo que su user_ids son incrementales, usted podría estar interesado en el uso de SETBIT para establecer un 1 o un 0 a poco desplazamiento de un usuario para realizar un seguimiento de la presencia. A continuación, puede hacer cosas interesantes como el nuevo BITCOUNT para ver cuántos usuarios están en línea y GETBIT para determinar si un usuario específico está en línea.

La forma en que he resuelto su problema más específicamente en el pasado es mediante la señalización de un gestor de suscripción que me he suscrito a un canal. Luego, el administrador "repite" el canal enviando un mensaje en blanco para confirmar que hay un suscriptor, y ocasionalmente hace ping al canal a partir de entonces para determinar si el usuario aún está en línea. No es ideal, pero es mejor que usar DEBUG CHANNELS en producción.

+0

¡Gran sugerencia! Tuve la misma necesidad ahora y logré escribir sobre ello publicando 'null' en el canal para obtener la cantidad de suscriptores. Luego, en el oyente, compruebo si el mensaje es Ninguno y me lo salteo, si es así. ¡Salud! –

1

partir de la versión 2.8.0 Redis tiene un comando pubsub que ayudaría en este caso:

http://redis.io/commands/pubsub

Observación: Actualmente el estado de 2.8.0 no es estable todavía (RC2)

4

a partir de Redis 2.8 que puede hacer:

PUBSUB CHANNELS [pattern] 

el tiene O (N) complejidad PUBSUB CHANNELS command, donde N es el número de canales activos.

Así, en su caso:

redis-cli PUBSUB CHANNELS user* 

daría desea que desea.

Cuestiones relacionadas