Create a Simple Chat Room with Redis PubSub

Written by Dan Sackett on November 11, 2014

When it comes to NoSQL, I believe that Redis is the king thanks to its ease of use and diversity.

I plan on doing a few posts on Redis this week, but I wanted to start off with something to show how easy it is to get started with it. That said, let's define what Redis is first. At it's bare minimum, it's a key value store. It allows persistent data but also works very well as a medium to process things. If you've ever heard of memcached think of Redis along those lines. Like Memcached, it store values in memory so accessing and working with data in the store is incredibly fast.

I've mentioned it in the past when talking about working with celery. It's great for usage with message queues because of the speed and many data sets. With that outlined, let's get into a working example to hook you in.

Building a Chatroom

One of the cool things that Redis supplies out of the box is a pub/sub module. You can connect to the Redis database and then set your script to subscribe to a specific channel. When subscribed, other users can publish content to that channel and the results will be collected and available for the channel. This is how chatrooms work. You subscribe to a certain room, and users publish content which is then printed to the room.

First of all, let's make sure we have Redis installed:

$ sudo apt-get install redis-server
$ sudo redis-server start
$ redis-cli PING
PONG

If those commands work for you, then you're all setup!

I'm going to be using the awesome redis-py library to do this in Python. To get started, use pip to install the dependency:

$ pip install redis

With that done, let's create our first file. Make a file named settings.py.

import redis

config = {
    'host': 'localhost',
    'port': 6379,
    'db': 0,
}

r = redis.StrictRedis(**config)

Let's break this down:

This basic config will get us our instance so that we can use it in our other app files. Let's see them.

Create a new file called pub.py:

from settings import r
import sys

if __name__ == '__main__':
    name = sys.argv[1]
    channel = sys.argv[2]

    print 'Welcome to {channel}'.format(**locals())

    while True:
        message = raw_input('Enter a message: ')

        if message.lower() == 'exit':
            break

        message = '{name} says: {message}'.format(**locals())

        r.publish(channel, message)

And breaking this example down:

The only new thing here is this publish() method which allows us to select the channel and the message to pass. When we do so, all participants subscribed to the channel will get our messages. Let's see our subscriber now.

Create a new file called sub.py:

from settings import r
import sys

if __name__ == '__main__':
    channel = sys.argv[1]

    pubsub = r.pubsub()
    pubsub.subscribe(channel)

    print 'Listening to {channel}'.format(**locals())

    while True:
        for item in pubsub.listen():
            print item['data']

And one last break down will tell us that:

Very simple and the best thing is that the app is done. Go back to your terminal and open three windows. First off, start the subscriber:

$ python sub.py PYTHON
Listening to PYTHON

As you see, this continues to run and waits for messages to be published. Let's give it some messages. In another terminal window run:

$ python pub.py Dan PYTHON
Welcome to PYTHON
Enter a message:

So far so good. Test it out by typing a message and watch the subscriber terminal window. You should see messages from one terminal appearing in the other terminal now! Let's open a third terminal window and make it act like a real chatroom.

$ python pub.py Jesse PYTHON
Welcome to PYTHON
Enter a message:

Now messages from one terminal window will be from Dan and the other will be from Jesse. Since our subscriber is just listening to the channel, we can have any number of users in this room. Try typing in both publisher windows and see the messages show up with the subscriber.

Nice and simple.

Conclusion

As you see, we didn't have to do much at all to get a chatroom example built in Redis. Of course, Redis does a lot more than just the pub/sub pattern for us and I'll be elaborating more on that this week. For now, play around with this example and if you want to see some more Redis jump into the Redis CLI by typing redis-cli in your terminal.


python redis

comments powered by Disqus