У Django есть способ открыть HTTP-соединение с длительным опросом?
Оставьте подключение открытым, пока не произойдет событие.
Ответы
Ответ 1
Взгляните на Django/Comet (Push): наименьшее из всех зол? или Последняя рекомендация для кометы в Python? - COMET - это еще одно имя для "ajax long-poll".
По-видимому, наиболее распространенный подход заключается не в том, чтобы делать это непосредственно в django, а с помощью дополнительного демона (вероятно, потому, что, например, Apache не справляется с большим количеством долгоживущих соединений). В настоящее время nodejs + socketio довольно популярен для этого (и он даже может использовать WebSockets) - вам просто нужно найти хороший способ передачи данных между двумя вещами. Если он является однонаправленным (например, только для широковещательных сообщений для всех подключенных клиентов), redis pubsub queue не является плохим вариантом для этого.
Но http://code.google.com/p/django-orbited/, вероятно, является самым решением djangoish.
Ответ 2
Для будущих читателей:)
Я создал простые просмотры класса django для опроса, используя Gevent, вы можете найти его на github на https://github.com/tbarbugli/django_longpolling или получить его из pypi ( django_longpolling)
EDIT: я сделал еще один эксперимент/развертывание с django long polling/async workers, и могу сказать, что, если возможно, выбор внешнего демона - очень хороший выбор, особенно если вы используете db (при использовании асинхронного рабочего вам нужно пул соединений db или у вас будет количество рабочих подключений, связанных с вашими ограничениями на соединение db, которые не являются необходимыми).
Ответ 3
Я думаю, что лучший способ асинхронной связи с Django - иметь сервер node, прослушивающий в другом порту, и использовать 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>