2011-01-24 39 views
15

保持连接处于打开状态,直到发生事件。Django是否有办法打开HTTP长轮询连接?

+0

民意调查?不知道什么是长杆连接,尽管听起来很棒。 ;) –

+0

那会是什么事? Django是一个* web *框架,用于处理请求和响应,而不是信号协议。对不起,如果我误解你的问题。 – AndiDog

+0

长轮询是一种用于AJAX应用程序的方法,只要发生服务器上的事件,它就应该执行某些操作。所以基本上你会开始一个AJAX请求,这个请求不会立即处理,而是一旦发生某个事件。得到响应后,通常立即重新启动请求。 – ThiefMaster

回答

14

查看Django/Comet (Push): Least of all evils?The latest recommendation for Comet in Python? - COMET是“ajax long-polling”的另一个名称。

显然最常用的方法并不是直接在django中进行,而是在附加守护进程的帮助下进行(可能是因为例如Apache不能很好地处理长连接)。现在nodejs + socketio在这方面非常流行(它甚至可以使用WebSockets) - 你只需要找到一个在这两件事之间传递数据的好方法。如果它是单向的(例如,只是向所有连接的客户端广播),redis pubsub队列不是一个不错的选择。

http://code.google.com/p/django-orbited/可能是最djangoish的解决方案。

+0

轨道很好;但下一个最好的事情是[服务器发送事件](http://en.wikipedia.org/wiki/Server-sent_events);这[在html5rocks.com上发布](http://www.igvita.com/2011/08/26/server-sent-event-notifications-with-html5/)解释更多,并提供了一些您可以使用的代码。 –

+0

对于python中的socket.io实现:https://gevent-socketio.readthedocs.org/en/latest/ – turtlemonvh

9

对于未来的读者:)

我创建使用GEVENT一个简单的长轮询的Django类的观点,你可以找到它在github上https://github.com/tbarbugli/django_longpolling或从PyPI将得到它(django_longpolling)

编辑:我做了一些进一步的实验/部署与Django长轮询/异步工作者,我可以说,如果可能的话选择一个外部守护进程是一个很好的选择,尤其是如果你使用数据库(当使用异步工作者时,你需要一个数据库连接池或你将有大量的工作连接绑定到你的数据库连接限制,这是不可理想的)。

2

我认为与Django进行异步通信的最佳方式是让一个节点服务器在另一个端口中监听并使用Socket.io的api客户端。通过这种方式,您不依赖于django模块的支持,并且非常简单:节点侦听来自客户端的请求,将该请求转换为发送请求并将其发送给Django以获取侦听Django的端口。 是我认为最好的方式。

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> 
相关问题