2011-01-24 27 views
15

Để kết nối mở, cho đến khi xảy ra sự kiện.Django có cách mở một kết nối thăm dò ý kiến ​​HTTP dài không?

+0

thăm dò? Không biết kết nối cực dài sẽ là gì, mặc dù nó có vẻ tuyệt vời. ;) –

+0

Sự kiện đó sẽ là gì? Django là một khuôn khổ * web * làm việc với các yêu cầu và phản hồi, không phải là một giao thức báo hiệu. Xin lỗi nếu tôi hiểu sai câu hỏi của bạn. – AndiDog

+0

Bỏ phiếu dài là một phương pháp được sử dụng cho các ứng dụng AJAX nên thực hiện điều gì đó ngay sau khi sự kiện trên máy chủ xảy ra. Vì vậy, về cơ bản bạn bắt đầu một yêu cầu AJAX mà không được xử lý ngay lập tức nhưng ngay sau khi một sự kiện nào đó xảy ra. Sau khi nhận được phản hồi, yêu cầu thường được khởi động lại ngay lập tức. – ThiefMaster

Trả lời

14

Hãy xem Django/Comet (Push): Least of all evils? hoặc The latest recommendation for Comet in Python? - COMET là một tên khác cho "ajax long-polling".

Rõ ràng cách tiếp cận phổ biến nhất là không thực hiện trực tiếp trong django nhưng với sự trợ giúp của một daemon bổ sung (có thể vì Apache không hoạt động tốt với nhiều kết nối lâu dài). Ngày nay nodejs + socketio là khá phổ biến cho điều này (và nó thậm chí có thể sử dụng WebSockets) - bạn chỉ cần tìm một cách tốt đẹp để truyền dữ liệu giữa hai thứ. Nếu nó là một chiều (ví dụ: chỉ các chương trình phát sóng cho tất cả các máy khách được kết nối), một hàng đợi redis pubsub không phải là một lựa chọn tồi cho việc này.

Nhưng http://code.google.com/p/django-orbited/ có lẽ là giải pháp djangoish nhất.

+0

Orbited là tốt đẹp; nhưng điều tốt nhất tiếp theo là [Server Sent Events] (http://en.wikipedia.org/wiki/Server-sent_events); [đăng trên html5rocks.com] (http://www.igvita.com/2011/08/26/server-sent-event-notifications-with-html5/) giải thích thêm và cung cấp một số mã bạn có thể sử dụng. –

+0

Để thực hiện socket.io trong python: https://gevent-socketio.readthedocs.org/en/latest/ – turtlemonvh

9

Đối với các độc giả tương lai :)

Tôi tạo ra một quan điểm lớp django bỏ phiếu dài đơn giản sử dụng Gevent, bạn có thể tìm thấy nó trên github trên https://github.com/tbarbugli/django_longpolling hoặc làm cho nó từ pypi (django_longpolling)

EDIT: Tôi đã làm một số thử nghiệm/triển khai thêm với công cụ bỏ phiếu dài/không đồng bộ của django và tôi có thể nói rằng nếu có thể chọn một daemon bên ngoài là rất lựa chọn tốt, đặc biệt là nếu bạn sử dụng db (khi sử dụng công nhân không đồng bộ, bạn cần một hồ bơi kết nối db hoặc bạn sẽ có số lượng kết nối công nhân bị ràng buộc với giới hạn kết nối db của bạn mà không phải là điều đáng khinh bỉ).

2

Tôi nghĩ cách tốt nhất để giao tiếp không đồng bộ với Django là có máy chủ nút nghe ở cổng khác và sử dụng ứng dụng api của Socket.io. Bằng cách này, bạn không phụ thuộc vào sự hỗ trợ của các mô-đun cho django và rất đơn giản: Node lắng nghe yêu cầu từ khách hàng, chuyển đổi yêu cầu này trong một yêu cầu gửi và gửi đến Django cho cổng nghe Django. Là cách tốt nhất tôi nghĩ.

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> 
Các vấn đề liên quan