One common pattern that we find with Redis is that we have clients of one kind or
another (server processes, users in a chat, and so on) that listen or wait for messages
on their own channel. They’re the only ones that receive those messages. Many programmers will end up using Redis PUBLISH and SUBSCRIBE commands to send
messages and wait for messages, respectively. But if we need to receive messages,
even in the face of connection issues, PUBLISH and SUBSCRIBE don’t help us much.
Breaking from our game company focus, Fake Garage Startup wants to release a
mobile messaging application. This application will connect to their web servers to
send and receive SMS/MMS-like messages (basically a text or picture messaging
replacement). The web server will be handling authentication and communication
with the Redis back end, and Redis will be handling the message routing/storage.
Each message will only be received by a single client, which greatly simplifies our
problem. To handle messages in this way, we use a single LIST for each mobile client.
Senders cause messages to be placed in the recipient’s LIST, and any time the recipient’s
client makes a request, it fetches the most recent messages. With HTTP 1.1’s ability
to pipeline requests, or with more modern web socket support, our mobile client
can either make a request for all waiting messages (if any), can make requests one at a
time, or can fetch 10 and use LTRIM to remove the first 10 items.
Because you already know how to push and pop items from lists from earlier sections,
most recently from our first-in, first-out queues from section 6.4.1, we’ll skip including
code to send messages, but an
example incoming message
queue for user jack451 is illustrated
in figure 6.11.
With LISTs, senders can also be notified if the recipient hasn’t been connecting recently, hasn’t received their previous messages, or maybe has too many pending messages; all by checking the messages in the recipient’s LIST. If the system were limited
by a recipient needing to be connected all the time, as is the case with PUBLISH/
SUBSCRIBE, messages would get lost, clients wouldn’t know if their message got
through, and slow clients could result in outgoing buffers growing potentially without
limit (in older versions of Redis) or getting disconnected (in newer versions of Redis).
With single-recipient messaging out of the way, it’s time to talk about replacing
PUBLISH and SUBSCRIBE when we want to have multiple listeners to a given channel.