2011-01-24 8 views
15

Lasciare aperta la connessione, fino a quando si verifica un evento.Django ha un modo per aprire una connessione HTTP poll lungo?

+0

sondaggio? Non ho idea di cosa sarebbe una lunga connessione polare, anche se suona fantastica. ;) –

+0

Quale evento sarebbe? Django è un framework * web * che funziona con richieste e risposte, non con un protocollo di segnalazione. Scusa se frainteso la tua domanda. – AndiDog

+0

Il polling lungo è un metodo utilizzato per le app AJAX che dovrebbe eseguire un'operazione non appena si verifica un evento sul server. Quindi in pratica si avvia una richiesta AJAX che non viene gestita immediatamente ma non appena si verifica un determinato evento. Di solito, dopo aver ricevuto una risposta, la richiesta viene immediatamente riavviata. – ThiefMaster

risposta

14

Dai un'occhiata a Django/Comet (Push): Least of all evils? o The latest recommendation for Comet in Python? - COMET è un altro nome per "ajax long-polling".

Apparentemente l'approccio più comune non è farlo direttamente in django ma con l'aiuto di un demone aggiuntivo (probabilmente perché, ad esempio, Apache non funziona bene con molte connessioni di lunga durata). Al giorno d'oggi nodejs + socketio è molto popolare per questo (e può persino usare WebSockets) - devi solo trovare un modo carino per passare i dati tra le due cose. Se è unidirezionale (ad esempio, solo trasmissioni broadcast a tutti i client connessi), una coda redub pubub non è una cattiva opzione per questo.

Ma http://code.google.com/p/django-orbited/ è probabilmente la soluzione più djangoish.

+0

Orbited è bello; ma la cosa migliore è [Server Sent Events] (http://en.wikipedia.org/wiki/Server-sent_events); questo [post su html5rocks.com] (http://www.igvita.com/2011/08/26/server-sent-event-notifications-with-html5/) spiega di più e fornisce del codice che è possibile utilizzare. –

+0

Per un'implementazione socket.io in python: https://gevent-socketio.readthedocs.org/en/latest/ – turtlemonvh

9

Per i futuri lettori :)

ho creato una semplice vista di classe Django lungo elettorali utilizzando Gevent, lo si può trovare su github su https://github.com/tbarbugli/django_longpolling o scarica da PyPI (django_longpolling)

EDIT: ho fatto qualche ulteriore esperimento/dispiegamento con django long polling/async worker e posso dire che se possibile optare per un demone esterno è una molto buona scelta, specialmente se si usa il db (quando si usa un operatore asincrono è necessario un pool di connessioni db o hai intenzione di avere la quantità di connessioni di lavoro legate ai tuoi limiti di connessione db che non è possibile).

2

Penso che il modo migliore per la comunicazione asincrona con Django sia avere un server nodo in ascolto su un'altra porta e utilizzare il client API di Socket.io. In questo modo, non sei dipendente dal supporto dei moduli per django ed è molto semplice: Node ascolta la richiesta dal client, converte questa richiesta in una richiesta di posta e invia a Django per la porta che ascolta Django. È il modo migliore che penso.

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> 
Problemi correlati