19

Leave the connection open, until an event occurs.

TIMEX
  • 259,804
  • 351
  • 777
  • 1,080
  • poll? No idea what a long pole connection would be, though it sounds awesome. ;) – Dominic Rodger Jan 24 '11 at 22:10
  • What event would that be? Django is a *web* framework working with requests and responses, not a signalling protocol. Sorry if I misunderstand your question. – AndiDog Jan 24 '11 at 22:14
  • Long polling is a method used for AJAX apps which should do something as soon as an event on the server occurs. So basically you start an AJAX request which isn't handled immediately but as soon as a certain event occurs. After getting a response the request is usually immediately restarted. – ThiefMaster Jan 24 '11 at 22:24
  • @ThiefMaster. Yes, that's exactly what I want to do. How do I do that? – TIMEX Jan 24 '11 at 22:29

4 Answers4

16

Have a look at Django / Comet (Push): Least of all evils? or The latest recommendation for Comet in Python? - COMET is another name for "ajax long-polling".

Apparently the most common approach is not doing it directly in django but with the help of an additional daemon (probably because e.g. Apache doesn't do well with lots of long-living connections). Nowadays nodejs+socketio is pretty popular for this (and it can even use WebSockets) - you just need to find a nice way to pass data between the two things. If it's unidirectional (e.g. just broadcasts to all connected clients) a redis pubsub queue is not a bad option for this.

But http://code.google.com/p/django-orbited/ is probably the most djangoish solution.

Community
  • 1
  • 1
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • Orbited is nice; but the next best thing is [Server Sent Events](http://en.wikipedia.org/wiki/Server-sent_events); this [post on html5rocks.com](http://www.igvita.com/2011/08/26/server-sent-event-notifications-with-html5/) explains more and provides some code you can use. – Burhan Khalid Jan 13 '13 at 13:42
  • 1
    For a socket.io implementation in python: https://gevent-socketio.readthedocs.org/en/latest/ – turtlemonvh Dec 18 '13 at 14:13
9

For the future readers :)

I created a simple long polling django class views using Gevent, you can find it on github on https://github.com/tbarbugli/django_longpolling or get it from pypi (django_longpolling)

EDIT: I did some further experiment / deployment with django long polling / async workers and I can say that if possible opting to an external daemon is a very good choice, especially if you use the db (when using async worker you need a db connection pool or you are going to have the amount of worker connections bound to your db connection limits which is not desiderable).

Tommaso Barbugli
  • 11,781
  • 2
  • 42
  • 41
1

I think the best way to asynchronous communication with Django is have a node server listening in another port and use the api client of Socket.io. In this way, you aren't dependent of the support of the modules for django and is very simple: Node listening the request from client, convert this request in a post request and send to Django for the port which listen Django. Is the best way i think.

server.js

var http=require('http');
var server = http.createServer().listen(3000);
var io=require('socket.io').listen(server);
var querystring=require('querystring');

io.on('connection',function(socket){
   console.log('Connected to the client');
   socket.on('new comment',function(data){
      console.log('Web--->Node');
      var values=querystring.stringify(data);
      console.log(values);
      var options={
        hostname:'localhost',
        port:'8000',
        path:'/create-comment',
        method:'POST',
        headers:{
          'Content-Type':'application/x-www-form-urlencoded',
          'Content-Length':values.length
        }
      }
      var request=http.request(options, function(response){
        response.setEncoding('utf8');
        response.on('data',function(data){
          //Here return django
          console.log('Django-->Node');
          io.emit('return comment',data);
        });
      });

      request.write(values);
      request.end();
   });
});

views.py

def trysock(request):
    print 'In tryshok'
    comments=Comment.objects.all()
    dic = {
              'name': 'User',
              'form': CommentForm(),
              'comments': comments
          }

    return render(request,'index.html',dic)

@csrf_exempt
def create_comment(request):
    print 'Django<---Node'
    Comment.objects.create(
            user = request.POST['user'],
            comment = request.POST['comment']
        )

    response = JsonResponse({'user' : request.POST['user'], 'comment' : request.POST['comment']})
    print response.content
    return HttpResponse(response.content)

index.html

<div class='col-md-12'>
       <div class='col-md-6'>
         <form method='POST'>
         {% csrf_token %}
         {{form.comment}}
         <button id='boton'>Comentar</button>
         </form> 
       </div>

       <div id='comentarios' class='col-md-6'>
         {% for comment in comments %}
         <p>{{ comment.user }} - {{ comment.comment}}</p>
         {% endfor %}
       </div>
     </div>
    <!-- Fin Formulario comentarios -->

   </div>
    <script>
          var socket=io.connect('http://localhost:3000');
          console.log(socket);
          $('#boton').on('click',Comentar);
          function Comentar(e){
            console.log('Comentar(e)')
            e.preventDefault();
            var datos = {
              user:"baurin",
              comment : 'comentario de prueba'
            };
            socket.emit('nuevo comentario',datos);
            console.log('Enviando....: '+datos.user + '-' + datos.comment);
          }
          socket.on('devolviendo comentario', function(data){
              console.log('Recibiendo...');
              var dato = JSON.parse(data);
              $('#comentarios').prepend('<p>' + dato.user + '-' + dato.comment + '</p>')
          });
        </script> 
boatcoder
  • 17,525
  • 18
  • 114
  • 178
Baurin Leza
  • 2,004
  • 1
  • 13
  • 15
0

In 2022 the official django channels lets you handle long polling workloads.

Michał Jabłoński
  • 1,129
  • 1
  • 13
  • 15