I came across this article: http://maxburstein.com/blog/realtime-django-using-nodejs-and-socketio/
Which has steered me in the somewhat right direction.
I currently have an iOS front end and a Django back end. I use Gunicorn to serve data to the front end application. The communication between my iOS application and my backed is REST based. I simply send JSON back and forth. I don't serve any webpages. Just JSON responses.
I've implemented a simple Post & Comment Model:
class Post(models.Model):
user = models.ForeignKey(User)
blog = models.CharField(max_length=5000)
class Comment(models.Model):
comment = models.CharField(max_length=140)
user = models.ForeignKey(User)
post_id = models.ForeignKey(Post)
created_at = models.DateTimeField(auto_now_add=True)
Users can make blog posts and other users can comment on them. So if userX has a blog post and userY comments on it. I would like to notify userX that userY commented on his/her post.
I used to rely on pyAPNS to notify users; a python wrapper that uses Twisted to send notifications to APNS, but if userX turns off push notifications for my app, then userX will not be able to receive in-app notifications. So I'm out of luck.
I only care about in-app notifications. I would still like userX to receive live updates while he is in the app.
Django can publish the message to a channel on Redis when a user makes a POST request. Node.js will subscribe to that channel and socket.io will send it out to that particular user.
Here is a stripped down version of my views.py where the comment object is created. I send the id the user who made the comment, the id of the post, and the id of the user who made the blog post. The user will make a post request to this url with json: http://example.com:8000/upload-comment/
def UploadComment(request):
data = json.loads(request.body)
redis_server = redis.Redis(host='12.345.678.9', port=6379, db=0, password='mypassword')
newComment = Comment()
newComment.comment = data['comment']
newComment.user_id = data['user_id']
newComment.post_id = data['post_id']
newComment.save()
PostOwner = data['post_owner_id'] #id of the blog post owner
# Need to send a notification to PostOwner
response_data = []
response_data.append(
{'send_notifcation_to': PostOwner
'action': 'comment'
'comment_by': newComment.user.username)}
redis_server.publish("notifications", json.dumps(response_data))
return HttpResponse('Request Successful')
Node.js Implementation (According to Max Burstein's Article from Above)
var http = require('http');
var server = http.createServer().listen(4000);
var io = require('socket.io').listen(server);
And this is as far as I get :( I know this is quite sad but I'm left with many questions. How can I subscribe node.js to the remote Redis server that I published to from Django? How many clients can connect to this socket? is there limit? is a socket created for every client? or does every client listen in on the same socket? Can I send json data over this socket to one specific client? I know this is one big mammoth of post , but I'm in need of desperate help. If I wasn't clear with something, please do let me know so that I can edit the question. Thank you!
I'd definitely not use node.js for this. You can handle websockets in Python just fine, with Celery or gevent or whatever.
Just create a thread which registers to Redis and listens for new messages.
When the user connects, put the socket into a weak-value hash indexed by the user's name; when a message for them arrives, look up the destination username in that hash and send it off. Weak-value because it cleans up after itself when the user disconnects. Simple, really.
I'd also send new messages to the server using the websocket instead of HTTP-PUT.
Take a look at the implementation here: http://blog.sneawo.com/blog/2013/02/08/real-time-messaging-in-django-using-node-dot-js-and-redis/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With