2012-07-14 96 views
5

我正在寫一個簡單的Web應用程序使用南希。至少有一個請求導致未知長度的流,所以我無法提供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 2014-05-15 15:47:06

+0

我不記得了,對不起。 – 2014-05-15 16:04:06

+0

在這個問題上看到標記的答案=> http://stackoverflow.com/questions/29953301/stream-an-sqlfile-stream-using-nancy – sp3tsnaz 2017-03-28 10:01:19

回答

4

您必須在每個Write()之後撥打Flush(),否則響應會被緩衝。而且,Google Chrome在全部收到之前不會呈現輸出。

我通過編寫一個簡單的客戶端應用程序發現了這一點,該應用程序在響應流到達時記錄了它正在讀取的內容。

+0

那麼這是「排序」? – 2012-07-18 07:53:52

+1

不是。 'BufferOutput'的更改不在南希核心中,它只適用於ASP.NET託管。對於WCF,您必須更改WebHttpBinding,我無法使自託管正常工作,並且我無法看到OWIN託管的任何方式。 – 2012-07-18 08:42:16

+0

@RogerLipscombe你有沒有遇到過這種情況?我試圖得到這與NancyFx + ASP.NET的工作 – RPM1984 2015-05-15 01:57:13

5

在我的實驗過程中,我發現我需要以下配置。首先,根據Nancy Wiki中的說明設置您的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頭。

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; 
}; 

我指定的每塊比以前的例子更多的內容,由於最小尺寸先於其他渲染文檔之前:相反,以下路線定義似乎從我的IIS Express開發服務器的結果正確地流Chrome瀏覽器StackOverflow questions

0

如果使用.NET 4.5+,則可以使用Stream.CopyTo而不是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; 
}