Как транслировать HttpResponse с Django - PullRequest
53 голосов
/ 27 мая 2010

Я пытаюсь получить «привет мир» потоковых ответов, работающих на Django (1.2). Я понял, как использовать генератор и функцию yield. Но ответ все еще не потоковый. Я подозреваю, что есть связующее программное обеспечение, которое может с ним работать - может быть, калькулятор ETAG? Но я не уверен, как это отключить. Может кто-нибудь помочь, пожалуйста?

Вот "привет мир" потокового вещания, который у меня есть:

def stream_response(request):
    resp = HttpResponse( stream_response_generator())
    return resp

def stream_response_generator():
    for x in range(1,11):
        yield "%s\n" % x  # Returns a chunk of the response to the browser
        time.sleep(1)

Ответы [ 2 ]

45 голосов
/ 27 мая 2010

Вы можете отключить промежуточное программное обеспечение ETAG с помощью декоратора условий .Это получит ваш ответ обратно через HTTP.Вы можете подтвердить это с помощью инструмента командной строки, например curl.Но, вероятно, этого будет недостаточно, чтобы ваш браузер отображал ответ во время потоковой передачи.Чтобы побудить браузер отображать ответ во время потоковой передачи, вы можете вытолкнуть кучу пробелов вниз по каналу, чтобы заставить его буферы заполниться.Пример следующий:

from django.views.decorators.http import condition

@condition(etag_func=None)
def stream_response(request):
    resp = HttpResponse( stream_response_generator(), content_type='text/html')
    return resp

def stream_response_generator():
    yield "<html><body>\n"
    for x in range(1,11):
        yield "<div>%s</div>\n" % x
        yield " " * 1024  # Encourage browser to render incrementally
        time.sleep(1)
    yield "</body></html>\n"
38 голосов
/ 17 ноября 2012

Большая часть промежуточного программного обеспечения django не позволит вам транслировать контент. Большая часть этого промежуточного программного обеспечения должна быть включена, если вы хотите использовать приложение администратора django, так что это может раздражать. К счастью, это было решено в django 1.5 release . Вы можете использовать StreamingHttpResponse , чтобы указать, что вы хотите передавать результаты обратно, и все промежуточное программное обеспечение, поставляемое с django, знает об этом и действует соответствующим образом, чтобы не буферизовать вывод содержимого, а отправлять его по прямой. Ваш код будет выглядеть следующим образом для использования нового объекта StreamingHttpResponse.

def stream_response(request):
    return StreamingHttpResponse(stream_response_generator())

def stream_response_generator():
    for x in range(1,11):
        yield "%s\n" % x  # Returns a chunk of the response to the browser
        time.sleep(1)

Примечание по Apache

Я протестировал вышеописанное на Apache 2.2 с Ubuntu 13.04. Модуль apache mod_deflate, который был включен по умолчанию в тестируемой мной установке, будет буферизовать контент, который вы пытаетесь транслировать, до тех пор, пока он не достигнет определенного размера блока, затем скопирует контент и отправит его в браузер. Это предотвратит работу приведенного выше примера. Один из способов избежать этого - отключить mod_deflate, добавив следующую строку в вашу конфигурацию apache:

SetEnvIf Request_URI ^/mysite no-gzip=1

Это обсуждается более подробно в Как отключить mod_deflate в apache2? вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...