Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Server Push Method

I developed a Django application which requires the server push (or comet) for the further enhancement. I first had successfully implemented the server push using the "orbited" which worked great in all the major browsers except the IE (yeah I know... this IE is screwing my life once again). Although the significance of the IE has been reduced greatly, I would still love to implement the server push that will work in ALL major platforms.

I have been googling for days and here are some options I found.

  1. Using evserver (https://code.google.com/p/evserver/)
  2. Using Django + Tornado framework

It seems like using the Django + Tornado platform is more ideal in the long run, but I couldn't really find a good example from which I can learn how to implement the server push combining two frameworks. The only example I found was

django-tornado-demo (https://github.com/bdarnell/django-tornado-demo/tree/master/testsite)

However, I am not sure if this project even handles the server push mechanism or otherwise, lacks some explanation.

Can anybody please direct me to a good example of the demo project that combines Django and Tornado together and actually implements the server push mechanism? Also, any information regarding this topic will be highly appreciated.

Thank you very much in advance.

like image 948
Chris P Avatar asked Mar 24 '23 20:03

Chris P


2 Answers

SockJS is the way to go: https://github.com/mrjoes/sockjs-tornado

First, make your environment ready:

pip install sockjs-tornado

Second, you have to setup Tornado:

application = django.core.handlers.wsgi.WSGIHandler()
container = tornado.wsgi.WSGIContainer(application)


tornado_app = tornado.web.Application(
    EchoSockjsRouter('/websocket')+
    [
        ('/source/([^/]+)', SourceHandler),
        ('.*', tornado.web.FallbackHandler, dict(fallback=container)),
    ]
)

HTTPServer(tornado_app).listen(port)
tornado.ioloop.IOLoop.instance().start()

'/source' is a Request handler (I use it for async with @gen.engine), '.*' works for Django, and EchoSockjsRouter is what you want:

from sockjs.tornado import SockJSRouter, SockJSConnection

class EchoWebSocket(SockJSConnection):
  def on_open(self, request):
      print "sockjs: open"

  def on_message(self, data):
      print "data: %r" % (data,)
      self.send(data)

  def on_comment(self, data):
      print "data: %r" % (data,)
      self.send(data)

  def on_close(self):
      print "sockjs: close"

def EchoSockjsRouter(prefix):
    return SockJSRouter(EchoWebSocket, prefix).urls

After that, you will need to setup the UI (I am using SockJS client, version 0.3.4, http://sockjs.org, MIT License):

<script src="<SockJS Javascript>"></script>
<script>
    socket = new SockJS('http://localhost:8000/websocket');
    socket.onmessage = function(e) {
        console.log(e.data);
    };
    socket.onclose = function() {
        console.log('closed :(');
    };
    socket.onopen = function() {
        console.log('opened :>');
        letTheMadnessBegin();
    };

    function letTheMadnessBegin() {
        // silly, but you get the idea
        socket.send(JSON.stringify({
            name: $('#name').text(),
            message: $('input').val()
        }));
    }
<script>

Well, you can make the script pretty inside $(function(){})... but besides that, you are ready to go: http://grab.by/mSv6, http://grab.by/mSuU (sorry for the 404, it is to make it realistic O.o). I took this pattern from: https://idea.popcount.org/2012-09-21-django-with-sockjs/

Please note that I tried with Socketio, Tornado WebSocket and some others. However SocketJS was incredibly straight-forward.

Regards.

like image 131
ericson.cepeda Avatar answered Mar 26 '23 09:03

ericson.cepeda


There's also Socket.IO, you can use it with gevent-socketio/django-socketio with Django. (API-wise pretty similar to the SockJS examples, maybe https://stackoverflow.com/a/11874593/183910 helps)

like image 29
Bernhard Vallant Avatar answered Mar 26 '23 11:03

Bernhard Vallant