【问题标题】:Does Django have a way to open a HTTP long poll connection?Django 有办法打开 HTTP 长轮询连接吗?
【发布时间】:2011-06-14 19:46:51
【问题描述】:

保持连接打开,直到发生事件。

【问题讨论】:

  • 投票?不知道长杆连接会是什么,尽管听起来很棒。 ;)
  • 那会是什么事件? Django 是一个处理请求和响应的 web 框架,而不是一个信令协议。对不起,如果我误解了你的问题。
  • 长轮询是一种用于 AJAX 应用程序的方法,它应该在服务器上发生事件时立即执行某些操作。所以基本上你启动一个 AJAX 请求,它不会立即处理,而是在某个事件发生时立即处理。收到响应后,请求通常会立即重新启动。
  • @ThiefMaster。是的,这正是我想要做的。我该怎么做?

标签: python django http rest


【解决方案1】:

我认为与 Django 进行异步通信的最佳方式是让节点服务器在另一个端口上侦听并使用 Socket.io 的 api 客户端。这样,你就不再依赖于模块对 django 的支持,并且非常简单:节点监听来自客户端的请求,将此请求转换为 post 请求并发送到 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> 

【讨论】:

    【解决方案2】:

    对于未来的读者:)

    我使用 Gevent 创建了一个简单的长轮询 django 类视图,您可以在 github 上的 https://github.com/tbarbugli/django_longpolling 上找到它或从 pypi (django_longpolling) 获取它

    编辑:我用 django 长轮询/异步工作人员做了一些进一步的实验/部署,我可以说,如果可能的话,选择外部守护程序是一个非常不错的选择,特别是如果你使用 db (当使用异步工作者时,您需要一个数据库连接池,否则您将有一定数量的工作者连接绑定到您的数据库连接限制,这是不可取的)。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      猜你喜欢
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      • 2013-01-02
      相关资源
      最近更新 更多