2012-07-14 13 views
5

私は、Nancyを使って簡単なWebアプリケーションを作成しています。少なくとも1つのリクエストで長さが不明なストリームが生成されるため、Content-Lengthを提供できません。 Transfer-Encoding: chunked、または(この場合は同様に受け入れ可能です。Connection: close)を使用したいと思います。NancyFXにストリーム出力を書き込むにはどうすればよいですか?

ナンシーソースコードを素早くハックしました。Response.BufferOutputを追加し、HttpContext.Response.BufferOutputfalseに設定するコードを追加しました。あなたはここにそれを見ることができます:

public class HomeModule : NancyModule 
{ 
    public HomeModule() 
    { 
     Get["/slow"] = _ => new SlowStreamResponse(); 
    } 

    private class SlowStreamResponse : Response 
    { 
     public SlowStreamResponse() 
     { 
      ContentType = "text/plain"; 
      BufferOutput = false; 
      Contents = s => { 
       byte[] bytes = Encoding.UTF8.GetBytes("Hello World\n"); 
       for (int i = 0; i < 10; ++i) 
       { 
        s.Write(bytes, 0, bytes.Length); 
        Thread.Sleep(500); 
       } 
      }; 
     } 
    } 

それは効果がないようです。応答は5秒後に一気に上がります。私はこの単純なWebRequestベースのクライアントをテストしました。

ナンシーでチャンク出力を使用するにはどうすればよいですか?私はASP.NETホスティングを使用していますが、私は他のホスティングオプションの回答に興味があります。

HttpListenerを使用して単純なサーバーを作成した場合、SendChunkedtrueに設定して、単純なクライアントが正しくチャンクで受信するチャンク出力を送信します。

+0

Nancyコードでは、どこでHttpContext.Response.BufferOutputを設定しましたか?そしてこれをOWINと連携させる方法を見つけましたか? – Hooligancat

+0

私は覚えていません、申し訳ありません。 –

+0

この質問のマークされた答えを見る=> http://stackoverflow.com/questions/29953301/stream-an-sqlfile-stream-using-nancy – sp3tsnaz

答えて

4

Write()の後にFlush()に電話する必要があります。それ以外の場合は、応答はバッファされます。さらに、Google Chromeはすべてが受信されるまで出力をレンダリングしません。

これは、到着時に応答ストリームから読み取った内容を記録した単純なクライアントアプリケーションを作成することで検出されました。

+0

これは「並べ替え」ですか? –

+1

実際にはありません。 'BufferOutput'の変更はNancyのコアではなく、ASP.NETホスティングのためだけに機能します。 WCFの場合、WebHttpBindingを変更する必要があります。自己ホスティングを正しく動作させることができず、OWINホスティングでは何もできません。 –

+0

@RogerLipscombeこれでどこにいらっしゃいましたか?私はNancyFx + ASP.NETでこれを動作させようとしています – RPM1984

5

私の実験中、私は以下の設定が必要であることを発見しました。まず、に記載されているようにweb.configファイルを設定します。 disableoutputbufferの値を設定するには、現在のところブートストラップを指定する必要があるようです。 Nancy.Hosting.Aspnet.DefaultNancyAspNetBootstrapperから継承し、構成ファイルで指定したクラスを作成すると、正常に動作しているように見えます。

<configSections> 
    <section name="nancyFx" type="Nancy.Hosting.Aspnet.NancyFxSection" /> 
</configSections> 
<nancyFx> 
    <bootstrapper assembly="YourAssembly" type="YourBootstrapper"/> 
    <disableoutputbuffer value="true" /> 
</nancyFx> 

その後、Transfer-Encodingヘッダーを設定しないでください。むしろ、以下のルート定義は正しくChromeに私のIIS Expressの開発サーバからの結果をストリーミングするために表示されます。

Get["/chunked"] = _ => 
{ 
    var response = new Response(); 
    response.ContentType = "text/plain"; 
    response.Contents = s => 
    { 
    byte[] bytes = System.Text.Encoding.UTF8.GetBytes("Hello World "); 
    for (int i = 0; i < 10; ++i) 
    { 
     for (var j = 0; j < 86; j++) 
     { 
     s.Write(bytes, 0, bytes.Length); 
     } 
     s.WriteByte(10); 
     s.Flush(); 
     System.Threading.Thread.Sleep(500); 
    } 
    }; 

    return response; 
}; 

私が原因最初の他に文書レンダリングする前に最小サイズに、前の例よりも、チャンクごとに多くのコンテンツを指定しましたStackOverflow questions

0

.NET 4.5以降を使用している場合は、代わりに、flushではなくStream.CopyToを使用できます。

Get["/chunked"] = _ => 
{ 
    var response = new Response(); 
    response.ContentType = "text/plain"; 
    response.Contents = s => 
    { 
    using(var helloStream = new MemoryStream(Encoding.UTF8.GetBytes("Hello World "))) 
     helloStream.CopyTo(s); 
    } 
    return response; 
} 
関連する問題