2011-01-24 15 views
15

Deje la conexión abierta, hasta que ocurra un evento.¿Tiene Django una manera de abrir una conexión HTTP de larga duración?

+0

encuesta? No tengo idea de lo que sería una conexión de polo largo, aunque suena increíble. ;) –

+0

¿Qué evento sería? Django es un * web * framework que trabaja con solicitudes y respuestas, no un protocolo de señalización. Lo siento si malinterpreto tu pregunta. – AndiDog

+0

El sondeo largo es un método utilizado para aplicaciones AJAX que debería hacer algo tan pronto como ocurra un evento en el servidor. Entonces, básicamente, comienzas una solicitud AJAX que no se maneja de inmediato sino tan pronto como ocurre un determinado evento. Después de obtener una respuesta, la solicitud generalmente se reinicia inmediatamente. – ThiefMaster

Respuesta

14

Eche un vistazo a Django/Comet (Push): Least of all evils? o The latest recommendation for Comet in Python? - COMET es otro nombre para "ajax long-polling".

Aparentemente, el enfoque más común no es hacerlo directamente en django sino con la ayuda de un daemon adicional (probablemente porque, por ejemplo, a Apache no le va bien con muchas conexiones de larga vida). Hoy en día, nodejs + socketio es bastante popular para esto (e incluso puede usar WebSockets); solo necesitas encontrar una buena manera de pasar datos entre las dos cosas. Si es unidireccional (por ejemplo, solo transmisiones a todos los clientes conectados), una cola redis pubsub no es una mala opción para esto.

Pero http://code.google.com/p/django-orbited/ es probablemente la solución más djangoish.

+0

Orbited es bueno; pero la siguiente mejor opción es [Eventos enviados por el servidor] (http://en.wikipedia.org/wiki/Server-sent_events); esta [publicación en html5rocks.com] (http://www.igvita.com/2011/08/26/server-sent-event-notifications-with-html5/) explica más y proporciona algún código que puede usar. –

+0

Para una implementación de socket.io en python: https://gevent-socketio.readthedocs.org/en/latest/ – turtlemonvh

9

Para los futuros lectores :)

he creado un sencillo vistas de clase django largo de votación utilizando GEvent, usted lo puede encontrar en GitHub en https://github.com/tbarbugli/django_longpolling o conseguirlo de PyPI (django_longpolling)

EDIT: lo hice algunos experimentos adicionales/implementación con django long polling/async workers y puedo decir que si es posible optar por un daemon externo es una buena opción muy, especialmente si usa el db (cuando usa el async worker necesita un grupo de conexión db o usted va a tener la cantidad de conexiones de trabajador ligadas a los límites de su conexión db que no es desable).

2

Creo que la mejor forma de comunicación asíncrona con Django es tener un servidor de nodos escuchando en otro puerto y usar el cliente de API de Socket.io. De esta manera, no dependes del soporte de los módulos para django y es muy simple: Node escucha la solicitud del cliente, convierte esta solicitud en una solicitud de envío y la envías a Django para el puerto que escucha Django. Es la mejor manera, creo.

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> 
Cuestiones relacionadas