7

Nancy を使用して単純な Web アプリケーションを作成しています。少なくとも 1 つのリクエストで長さが不明なストリームが発生したため、提供できませんContent-LengthTransfer-Encoding: chunked、または (この場合は同様に許容されます)を使用したいと思いConnection: closeます。

Nancy のソース コードを簡単にハックして、 とResponse.BufferOutputに設定HttpContext.Response.BufferOutputするコードを追加しましたfalse。ここでそれを見ることができます:

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ベースのクライアントでテストしました。

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

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

4

3 に答える 3

6

実験中に、次の構成が必要であることがわかりました。まず、 Nancy Wikiweb.configに記載されているようにファイルを設定します。値を設定するには (これが必要です)、現在、ブートストラップも指定する必要があるようです。から継承するアセンブリでクラスを作成し、構成ファイルでそれを指定すると、機能するように見えます。disableoutputbufferNancy.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ヘッダーを設定しないでください。むしろ、次のルート定義は、IIS Express 開発サーバーから Chrome に結果を正しくストリーミングしているように見えます。

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 の質問に記載されている最初のレンダリング前の最小サイズのため、前の例よりも多くのコンテンツをチャンクごとに指定しました

于 2016-06-14T19:20:08.123 に答える
4

Flush()各 の後に呼び出す必要がありWrite()ます。そうしないと、とにかく応答がバッファリングされます。さらに、Google Chrome は、すべてが受信されるまで出力をレンダリングしません。

これを発見したのは、受信した応答ストリームから読み取った内容をログに記録する単純なクライアント アプリケーションを作成することでした。

于 2012-07-14T18:44:24.753 に答える