How do I get the client id for the ISubscriber connection?

Viewed 476

I'm using the StackExchange.Redis NuGet package.

I would like to get the Client ID for the connection that is created when I call redis.GetSubscriber(). This method returns an object of type ISubscriber and creates a new connection to the redis server.

I can't find any properties or methods on this object that provides access to the client id of the connection it uses.

I know I can send the CLIENT ID command to redis, but this doesn't help as there doesn't appear to be a way to send this command manually via the ISubscriber object or via any of the objects accessible from it's methods and properties.

I know I can call redis.GetDatabase() and then run db.Execute("CLIENT", "ID"), but GetDatabase() creates a new connection, and the client id that is returned isn't the one being used by the ISubscriber object.

var redis = ConnectionMultiplexer.Connect("localhost:6379");

// This returns an ISubscriber object and creates a new connection
var subscriber = redis.GetSubscriber(); // I want the client id for this connection

// This returns an IDatabase object and also creates a new connection
var db = redis .GetDatabase();
var dbClientId = invalidatorDb.Execute("CLIENT", "ID"); // not the client id I want

Is anyone able to offer some suggestions?

1 Answers

This is a very interesting question; in particular:

  1. the CLIENT ID operation only exists from Redis 5.0 onwards
  2. the CLIENT ID operation cannot be performed once the connection is in subscriber mode

To see the latter, consider the following trace (with my comments after #)

> ping # check connection
< +PONG

> client id # check can get client id on vanilla connection
< :5

> subscribe foo # switch to subscriber mode
< *3
< $9
< subscribe
< $3
< foo
< :1

> client id # check can get client id on subscriber connection
< -ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context

This means that to get the CLIENT ID of a subscriber connection, we'd need to change the library to issue that command much earlier in the pipe than you have access to, before it becomes a subscriber. Effectively, we'd need to issue a speculative CLIENT ID just in case we need it later as part of the connection handshake. I'm not against this - it is cheap enough, and we could easily do it for all connections; but: it does require library changes.

I'm guessing this is because you're trying to implement CLIENT TRACKING with the REDIRECT option, as there aren't that many alternative uses for a subscriber client id.

Note: you could try and guess with CLIENT LIST, but I do not recommend this.

Related