Redis PubSub Messaging

Introduction

Welcome back! In this lesson, we will dive into another powerful feature of Redis: Publish/Subscribe (Pub/Sub) messaging. This topic builds on our understanding of Redis and introduces a dynamic way to enable real-time communication within your applications.

What You'll Learn

In this lesson, you will learn how to set up and use Redis Pub/Sub messaging to send and receive messages using C++ and Boost.Redis. We'll create a single program that demonstrates both subscribing to and publishing messages on a channel.

Important notes:

  • Dedicated connection for subscribers: The subscriber uses a separate Redis connection that operates in subscription mode.
  • Asynchronous event-driven model: We use Boost.Asio's io_context to handle asynchronous operations.
  • RESP3 push messages: Redis sends Pub/Sub messages as push events that we receive through async_receive.
  • Two connections: One for subscribing (enters special subscriber mode) and one for regular commands like PUBLISH.

Setting Up the Connections

Let's start by setting up our includes and creating two Redis connections:

C++
#include <boost/redis.hpp>
#include <boost/redis/src.hpp>  // Include in one translation unit only
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <chrono>

namespace net = boost::asio;
using boost::redis::connection;
using boost::redis::config;
using boost::redis::request;
using boost::redis::generic_response;
using boost::redis::logger;

int main()
{
    net::io_context ioc;

    // One connection dedicated to SUBSCRIBE (subscriber mode).
    auto sub_conn = std::make_shared<connection>(ioc);

    // Separate connection for regular commands like PUBLISH.
    auto pub_conn = std::make_shared<connection>(ioc);

    config cfg;
    cfg.addr.host = "127.0.0.1";
    cfg.addr.port = "6379";

    // Start both connections.
    sub_conn->async_run(cfg, logger{logger::level::disabled},
                        net::consign(net::detached, sub_conn));

    pub_conn->async_run(cfg, logger{logger::level::disabled},
                        net::consign(net::detached, pub_conn));

What's happening here:

  • We create an io_context, which is the event loop that drives all asynchronous operations.
  • We create two separate connections: sub_conn for subscribing and pub_conn for publishing.
  • Why two connections? Once a connection enters subscriber mode (after SUBSCRIBE), it can only receive push messages and cannot execute regular commands. That's why we need a separate connection for PUBLISH.
  • Both connections are started with async_run(), which establishes the connection asynchronously.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal