Real time messaging in Django using Node.js and Redis

Here, just a small example of this task. Assume you have django comments system enabled.

Then you need to add publishing of comments into redis. It can be done with comment_was_posted signal.

import redis
from django.contrib.comments.signals import comment_was_posted

def publish_comment(sender, comment, request):
    comment_json = {
        'comment': comment.comment,
        'user_name': comment.user_name,
        'submit_date': comment.submit_date}
    r = redis.StrictRedis()
    r.publish('channel_comments_%s_%s' % (comment.content_type.id, comment.object_pk), comment_json)

Your simplest Node.js server will look like:

var app = require('http').createServer(),
    io = require('socket.io').listen(app),
    logger  = io.log,
    redis = require('redis').createClient();

var port = process.argv[2];
app.listen(port);

io.configure( function() {
    io.set('close timeout', 60*60*24); // 24h time out
});

redis.psubscribe("channel_comments_*"); //subscribe by pattern

io.sockets.on("connection", function(socket) {
    redis.on("pmessage", function(pattern, channel, message) {
        socket.emit(channel, message);
    });
});

And javascript client in django template for the commented object:

{% raw %}
<script src="http://{{ NODE_JS_SERVER }}/socket.io/socket.io.js"></script>
<script>
    var socket = io.connect('http://{{ NODE_JS_SERVER }}');
    socket.on('channel_comments_{{ object_content_type_id }}_{{ object.id }}',
        function (data) {
            console.log(data);
            // add comment to list
        });
</script>
{% endraw %}

More info:

comments powered by Disqus