ServiceStack.Redis: IRedisClient.PublishMessage vs IMessageQueueClient.Publish - explanation

I am having a hard time separating the IRedisClient.PublishMessage and IMessageQueueClient.Publish and realize I must be mixing something up.

ServiceStack gives us the option to listen for pub/sub broadcasts like this:

static IRedisSubscription _subscription;
static IRedisClient redisClientSub;
static int received = 0;
static void ReadFromQueue()
{
    redisClientSub = redisClientManager.GetClient();
    _subscription = redisClientSub.CreateSubscription();

    _subscription.OnMessage = (channel, msg) =>
    {
        try
        {
            received++;
        }
        catch (Exception ex)
        {
                
        }
    };

    Task.Run(() => _subscription.SubscribeToChannels("Test"));
}

Looks nice, straightforward. But what about the producer?

When looking at the classes available, I thought that one could either user the IRedisClient.PublishMessage(string toChannel, string message) or IMessageQueueClient.Publish(string queueName, IMessage message).

string json = JsonConvert.SerializeObject(testReq);
redisClient.PublishMessage("Test", json);
// or:     
myMessageQueueClient.Publish("Test", new Message<CoreEvent>(testReq));

In both cases, you specificy the channel name yourself. This is the behaviour I am seeing:

  • the subscriber above only receives the message if I use IRedisClient.PublishMessage(string toChannel, string message) and never if I use IMessageQueueClient.Publish(string queueName, IMessage message)
  • If I publish using IRedisClient.PublishMessage, I expected the “Test” channel to be populated (if I view with a Redis browser), but it is not. I never see any trace of the queue (lets say I dont start the subscription, but producers adds messages)
  • If I publish using IMessageQueueClient.Publish(string queueName, IMessage message), the channel “Test” is created and the messages are persisted there, but never popped/fetched-and-deleted.

I need help in understanding the difference between the two. I have looked at source code and read all I can about it, but I haven’t found any documentation regarding IRedisClient.PublishMessage.

Thanks!

These clients should not be used interchangeably, you should only be using ServiceStack MQ clients to send MQ Messages or the Message<T> MQ Message wrapper.

The redis subscription is low level API to create a Redis Pub/Sub subscription, a more useful higher level API is the Managed Pub/Sub Server which wraps the pub/sub subscription behind a managed thread.

Either way, MQ Server is only designed to process messages from MQ clients, if you’re going to implement your own messaging implementation use your own messages & redis clients not the MQ clients or MQ Message<T> class.

Thanks. So, the IRedisClient.PublishMessage is not a “ServiceStack MQ client”?

Does this mean that:

  • IRedisClient.PublishMessage works only with the IRedisSubscription.CreateSubscription; these two are meant to work together, and are not part of ServiceStack MQ
  • IMessageQueueClient.Publish works only with RedisPubSubServer, and these two are meant to work together, and is part of the ServiceStack MQ

This means, what I did above is to use low-level API, to build a pub/sub mechanism, but there are higher-level APIs that is recommended?

No IRedisClient (& ServiceStack.Redis) APIs are for Redis Server, the PublishMessage API sends the redis PUBLISH command. IRedisSubscription creates a Redis Pub/Sub subscription, see Redis docs to learn how Redis Pub/Sub works. The ServiceStack.Redis library and all its APIs are just for Redis Server, it doesn’t contain any ServiceStack.Messaging MQ APIs.

So just use ServiceStack.Redis for your custom Redis Pub/Sub subscription implementation, i.e. don’t use any ServiceStack.Messaging APIs which is for ServiceStack MQ only.

Thanks for the clarification!