web-dev-qa-db-ja.com

DjangoでHttpResponseをストリーミングする方法

Django(1.2)で動作するストリーミング応答の 'hello world'を取得しようとしています。ジェネレータと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)
53
muudscope

condition decorator を使用して、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"
45
Leopd

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に関する注意

Ubuntu 13.04でApache 2.2で上記をテストしました。私がテストしたセットアップでデフォルトで有効にされたApacheモジュールmod_deflateは、特定のブロックサイズに達するまでストリーミングしようとしているコンテンツをバッファリングし、コンテンツをgzipしてブラウザに送信します。これにより、上記の例が希望どおりに動作しなくなります。これを回避する1つの方法は、Apache構成に次の行を追加してmod_deflateを無効にすることです。

SetEnvIf Request_URI ^/mysite no-gzip=1

これについては Apache2でmod_deflateを無効にする方法? の質問で詳しく説明しています。

38