簡體   English   中英

HttpClient和PushStreamContent

[英]HttpClient and PushStreamContent

我將RESTAPI(ASP.NET Web API)與PushStreamContent一起使用,效果很好。 HttpClient可以請求資源,並在服務器處理完整的請求之前獲取HTTP-Response(服務器仍然寫入推流)。

作為HttpClient,您必須做一件事:使用HttpCompletionOption.ResponseHeadersRead。

現在我的問題是:是否有可能這樣做呢? 從HttpClient->通過推送流將數據上傳到Web API?

我實現了如下,但Web api不會在客戶端關閉流之前獲取請求。

         var asyncStream = new AsyncStream(fs);
         PushStreamContent streamContent = new PushStreamContent(asyncStream.WriteToStream);
         content.Add(streamContent);

         HttpResponseMessage response = await c.SendAsync(new HttpRequestMessage(new HttpMethod("POST"), "http://localhost/...") { Content = content }, HttpCompletionOption.ResponseHeadersRead);

         response.EnsureSuccessStatusCode();

AsyncStream是我的代表類:

public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)

這對於Push-Stream是必需的。

這有可能嗎? 在將最后一個字節寫入流之前,HttpClient不會將請求發送到Web api。

我需要做什么? 問題出在客戶端還是服務器/ asp.net Web api端?

編輯:這是WriteToStream的實現(但我不使用磁盤中的文件,而是使用memorystream'myMemoryStream'(在構造函數中傳遞):

public void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
{
    try
    {
        var buffer = new byte[4096];

        using (var stream = myMemoryStream)
        {
            var bytesRead = 1;

            while (bytesRead > 0)
            {
                bytesRead = video.Read(buffer, 0, buffer.Length);
                outputStream.Write(buffer, 0, bytesRead);
            }
        }
    }
    catch (HttpException ex)
    {
        return;
    }
    finally
    {
        outputStream.Close();
    }
}

也許我必須做些事情:HttpContent內容,TransportContext上下文?

我找到了解決問題的方法:

我要設置:httpWebRequest.AllowReadStreamBuffering = false;

HttpClient 4.0默認情況下會進行緩沖,並且您無法訪問屬性AllowReadStreamBuffering,因此必須直接使用HttpWebRequest。 (或者您可以使用HttpClinet 4.5,這是默認行為“流式傳輸”),請參見: http : //www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api / 6.使用HttpClient)

第二個問題是提琴手:提琴手當前僅支持響應流而不是請求( 提琴手使HttpWebRequest / HttpClient行為出乎意料

對我有用的解決方案:

HttpWebRequest httpWebRequest = HttpWebRequest.Create(...)
httpWebRequest.Method = "POST";
         httpWebRequest.Headers["Authorization"] = "Basic " + ...;
         httpWebRequest.PreAuthenticate = true;
         httpWebRequest.AllowWriteStreamBuffering = false;
         httpWebRequest.AllowReadStreamBuffering = false;
         httpWebRequest.ContentType = "application/octet-stream";
         Stream st = httpWebRequest.GetRequestStream();
st.Write(b, 0, b.Length);
st.Write(b, 0, b.Length);
//...
         Task<WebResponse> response = httpWebRequest.GetResponseAsync();

         var x = response.Result;
         Stream resultStream = x.GetResponseStream();
//... read result-stream ...

確保執行requestMessage.Headers.TransferEncodingChunked = true; 在您的請求消息上...原因是如果您未設置此項,則HttpClient會在客戶端本身緩沖整個內容,以便找出請求的Content-length,這就是您注意到Web api的原因正在寫入流時,服務不會立即被調用...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM