Daily Knowledge Drop
A common use case for Redis
is as a key-value stored, generally for caching - however, in addition to this key-value store Redis
also has built in messaging functionality via pub/sub
.
Redis installation
Redis
is not officially supported on Windows - so to use it on Windows, either WSL2
(Windows Subsystem for Linux) has to be used, or the Redis container image (available from Docker Hub) running in Docker Desktop, for example.
For the examples below, the Redis
image from Docker Hub was used, running on Docker Desktop for Windows.
Subscriber
First let's look at the subscriber
side. A reference is required to the StackExchange.Redis
NuGet package for the following code:
using StackExchange.Redis;
// configure the connection to the Redis endpoint
using ConnectionMultiplexer redis =
ConnectionMultiplexer.Connect("localhost:6379");
ISubscriber subScriber = redis.GetSubscriber();
// subscribe to the "alwaysdeveloping" channel. This needs to match the channel name
// the publisher is using as well
subScriber.Subscribe(new RedisChannel("alwaysdeveloping",
RedisChannel.PatternMode.Auto),
(channel, message) =>
{
// this handler method will be called for each message received on the channel
Console.WriteLine($"[{DateTime.Now}] Message received: {message}");
});
Console.ReadKey();
Configuring the subscriber
is relatively straight forward:
- Define a connection to the specific
Redis
endpoint - Get a subscriber from the connection
- Subscribe to a specific channel (by name , alwaysdeveloping in the above)
- Specify the handler method to be called when a message is received
The code will execute until a key is read from the console, waiting for any message to be sent to the channel. When a message is sent to the channel, it will in turn be published to all
subscribers - it is possible to have multiple subscribers
, each subscriber will receive their own copy of the message
Publisher
Next let's look at the publisher
- configuring this is also as straightforward as the subscriber:
using StackExchange.Redis;
// configure the connection to the Redis endpoint
using ConnectionMultiplexer redis =
ConnectionMultiplexer.Connect("localhost:6379");
ISubscriber sub = redis.GetSubscriber();
// loop 100 times
for (int i = 0; i <= 100; i++)
{
// generate a unique id for each message
var id = Guid.NewGuid().ToString();
// publish to the "alwaysdeveloping" channel
await sub.PublishAsync(new RedisChannel("alwaysdeveloping",
RedisChannel.PatternMode.Auto),
$"Sample message with Id {id}");
Console.WriteLine($"Message with Id '{id}' published!");
Thread.Sleep(100);
}
The above code:
- Define a connection to the
Redis
endpoint - Get a subscriber from the connection
- Loops 100 times,
- Publishes a string to a specific channel (by name, alwaysdeveloping in the above)
Pub/Sub Execution
Executing the subscriber
first, so it is running waiting for messages, then executing the publisher
yields the following output:
Sample from the the Publisher:
Message with Id '1895b2c1-61c1-4be9-8ed2-7c6359018534' published!
Message with Id '01a27c11-984c-481a-b4d0-bc879b13674d' published!
Message with Id '49e799eb-cf4c-4847-a234-d79b8e40cd79' published!
Message with Id '25700248-edbc-4c70-aaef-5aca4cb0f24f' published!
Message with Id '6a4caee2-e9ad-446f-8e2c-156cebdf6a42' published!
Message with Id '061ef1ff-e830-408c-84db-bdf649c8c446' published!
Message with Id '358c78ba-e85a-481a-970a-1c67b2ca8b1d' published!
Message with Id '5101fe4a-86fb-4356-b0db-dea0f4f1a402' published!
Message with Id 'fe944b2c-c945-417c-bb61-8b7eb7bfe8f1' published!
Message with Id '1f6d26a0-35ab-4994-8293-1e2a9e672cee' published!
Message with Id '5e276d80-9ccd-403b-9435-80b8fda0e2d3' published!
Message with Id 'a3ea7ddd-6ac6-4b3e-b35d-1276ce20e1bd' published!
Sample from the Subscriber(s)
:
[2022/07/19 21:09:24] Message received: Sample message with Id 1895b2c1-61c1-4be9-8ed2-7c6359018534
[2022/07/19 21:09:24] Message received: Sample message with Id 01a27c11-984c-481a-b4d0-bc879b13674d
[2022/07/19 21:09:24] Message received: Sample message with Id 49e799eb-cf4c-4847-a234-d79b8e40cd79
[2022/07/19 21:09:24] Message received: Sample message with Id 25700248-edbc-4c70-aaef-5aca4cb0f24f
[2022/07/19 21:09:24] Message received: Sample message with Id 6a4caee2-e9ad-446f-8e2c-156cebdf6a42
[2022/07/19 21:09:24] Message received: Sample message with Id 061ef1ff-e830-408c-84db-bdf649c8c446
[2022/07/19 21:09:25] Message received: Sample message with Id 358c78ba-e85a-481a-970a-1c67b2ca8b1d
[2022/07/19 21:09:25] Message received: Sample message with Id 5101fe4a-86fb-4356-b0db-dea0f4f1a402
[2022/07/19 21:09:25] Message received: Sample message with Id fe944b2c-c945-417c-bb61-8b7eb7bfe8f1
[2022/07/19 21:09:25] Message received: Sample message with Id 1f6d26a0-35ab-4994-8293-1e2a9e672cee
[2022/07/19 21:09:25] Message received: Sample message with Id 5e276d80-9ccd-403b-9435-80b8fda0e2d3
[2022/07/19 21:09:25] Message received: Sample message with Id a3ea7ddd-6ac6-4b3e-b35d-1276ce20e1bd
Notes
Configuring Redis pub/sub
is incredibly simple and easy to implement, especially if there is a Redis instance setup (for caching for example). While not entirely comparable, having worked with other similar services such as RabbitMq and Kafka, this was by far the simplest to implement.
References
DevMentors - FeedR episode #5
Install Redis on Windows
Daily Drop 139: 16-08-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.