Search code examples
redispublish-subscribe

How does redis keep track of every client?


I am learning how to use Redis.

I am specifically learning the pub/sub functionality.

I am using ioredis with expressjs and nodejs.

I have come across this code

var Redis = require("ioredis");
var redis = new Redis();
var pub = new Redis();
redis.subscribe("news", "music", function(err, count) {
  // Now we are subscribed to both the 'news' and 'music' channels.
  // `count` represents the number of channels we are currently subscribed to.

  pub.publish("news", "Hello world!");
  pub.publish("music", "Hello again!");
});

redis.on("message", function(channel, message) {
  // Receive message Hello world! from channel news
  // Receive message Hello again! from channel music
  console.log("Receive message %s from channel %s", message, channel);
});

// There's also an event called 'messageBuffer', which is the same as 'message' except
// it returns buffers instead of strings.
redis.on("messageBuffer", function(channel, message) {
  // Both `channel` and `message` are buffers.
});

Now my question is:

How does redis know who has subscribed to what, so that it can send messages to them? Does every redis client have a unique id that they are identified with? (Like in the case with socket.io)


Solution

  • When a client subscribes to a channel or to a pattern - such subscription is referenced in:

    • server's map of channel -> list of subscribed clients - when subscribing to a named channel,
    • server's list of pattern subscriptions - in case of pattern subscription,
    • client's list of channel/pattern subscriptions.

    By server and client above I mean a structure in memory which represents various properties of the server and of each connected client, so as long as client is connected - its subscription is just a reference in those places listed above (thus there is no need to use any specific ID).

    When a message needs to be published:

    1. channel is looked up in server.pubsub_channels and when found - all clients subscribed to that channel will receive the message,
    2. when server.pubsub_patterns list is not empty - all pattern subscriptions are iterated and if a pattern matches - client that created this subscription is notified.

    Client's lists of channel/pattern subscriptions are used to keep track of what client subscribed to and to remove those subscriptions when client disconnects.

    You can also have a look at Redis/src/pubsub.c to see the details.