Есть ли у Django способ открыть длинное HTTP-соединение? - PullRequest
17 голосов
/ 25 января 2011

Оставьте соединение открытым, пока не произойдет событие.

Ответы [ 3 ]

16 голосов
/ 25 января 2011

Взгляните на Django / Comet (Push): наименьшее из всех зол? или Последняя рекомендация для Comet в Python? - COMET - это другое название для "ajax long-polling ".

По-видимому, наиболее распространенный подход заключается не в том, чтобы делать это напрямую в django, а с помощью дополнительного демона (возможно, потому, что, например, Apache не очень хорошо работает со многими долгоживущими соединениями).В настоящее время nodejs + socketio довольно популярен для этого (и он может даже использовать WebSockets) - вам просто нужно найти хороший способ передачи данных между двумя вещами.Если это однонаправленная (например, просто широковещательная рассылка всем подключенным клиентам), очередь redis pubsub не является плохим вариантом для этого.

Но http://code.google.com/p/django-orbited/, вероятно, является наиболее djangoish решением.

9 голосов
/ 13 января 2013

Для будущих читателей:)

Я создал простой длинный класс просмотра django с помощью Gevent, вы можете найти его на github на https://github.com/tbarbugli/django_longpolling или получить из pypi (django_longpolling)

РЕДАКТИРОВАТЬ: я провел еще один эксперимент / развертывание с длинными опрашивающими / асинхронными рабочими django, и я могу сказать, что, если возможно, выбор внешнего демона - это очень хороший выбор, особенно если вы используете db(при использовании асинхронного работника вам нужен пул соединений с БД или у вас будет количество рабочих соединений, привязанное к пределам вашего соединения с БД, что не является желательным).

2 голосов
/ 27 июля 2015

Я думаю, что лучший способ асинхронной связи с Django - это прослушивание сервером узлов другого порта и использование API-интерфейса Socket.io.Таким образом, вы не зависите от поддержки модулей для django и очень просты: Node прослушивает запрос от клиента, преобразует этот запрос в пост-запрос и отправляет в 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> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...