In Redis, how can I subscribe to the number of subscribers to a given key? (I want to know the number of connected users) I'm aware of PUBSUB NUMSUB, but as far as I know it is not possible to subscribe to its value, and polling it every second seems like a huge waste of resource, especially if hundreds/thousands of clients are doing it simultaneously.
#Subscribe to NUMSUB (number of connected users)?
9 messages · Page 1 of 1 (latest)
No built-in thing... The problem here is the pubsub channels are not keys, per se. It's a separate entity, so even keyspace notifications cannot be used directly.
- As workaround, you could generate simple key event right after the subscription and use the keyspace psubscribe to catch the new connected user. (Wont' catch disconnected anyways)
- Or just create a separate supplemental key to store this info. Both ways has + and -.
Be careful with pubsub numsub and other commands from that family, they are slow and server blocking..
(or just subscribe your watcher to a dedicated channel, and every user will generate PUBLISH <watcher-channel> "I am here at the channel foobar" Yet again, it won't give you abnormally disconnected subscribers, so time-to-time numsubs could be considered to be used)
Ok, thanks a lot! Too bad redis does not provide an efficient way to do that. To catch disconnected users, I was also maybe thinking to add on my graphql server a websocket hook on the disconnected part, to know when I should read it. Just, when you say they are slow, which magnitude is it? Like slow for 50 concurrent users subscribing to channels, or slow for 10000 users?
And does this also apply to "SUBSCRIBE" or only to PUBSUB *
I think it was not implemented due to the PSUBSCRIBE, you cannot guarantee how many listeners to your channel until your iterate over all of psubscribe patterns. You can imagine it's not so fast with many clients and active pubsub usage.
Pay attention to extra flags for each command marked as ACL categories. @slow means it can add latency to the server when many objects (subscribes, connected clients for the PUBSUB family) are registered when you issue the command.
https://redis.io/docs/latest/commands/pubsub-numsub/
ACL categories:
@pubsub, @slow
And yes, once upon a time I've modified the server codebase and added a custom connect/disconnect keyspace event to it, so at least I could trigger meaningful handler on that event. But again, it can hit the performance so they really don't wanna put something like that in the baseline.
I see, thanks a lot for mentionning the @slow category, very helpful!
Actually, I realized something: this approach does not even works, because I think my graphql server is making a single SUBSCRIBE query for all clients (which is actually not stupid)… So I think I'd better just count the number of websocket connections to my server. But I still want to use redis for this (maybe I have multiple servers), so I'm wondering, is it better to create one key to store the number of connected users, and one channel to signal new users, or to use keyspace notification? The fact that it is not enabled by default scary me a bit, so I'm wondering if a key + channel would not be more appropriate.