How do I write streamed output in NancyFX?

旧街凉风 提交于 2019-12-04 05:54:23
erdomke

During my experimentation, I discovered that I needed the following configuration. First, set up your web.config file as documented in the Nancy Wiki. It is worth noting that in order to set the disableoutputbuffer value (which is what we want), it appears that you currently need to also specify a bootstrapper. Creating a class in your assembly that inherits from Nancy.Hosting.Aspnet.DefaultNancyAspNetBootstrapper and specifying it in the configuration file appears to work.

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

Afterwards, you should not set the Transfer-Encoding header. Rather, the following route definition appears to correctly stream the results from my IIS Express development server to 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;
};

I specified more content per chunk than the previous example due to the minimum sizes prior to first render documented in other StackOverflow questions

You have to call Flush() after each Write(), otherwise the response is buffered anyway. Moreover, Google Chrome doesn't render the output until it's all received.

I discovered this by writing a simple client application that logged what it was reading from the response stream as it arrived.

If using .NET 4.5+, you can alternatively use Stream.CopyTo instead of flush.

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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!