网络条件差时如何处理文件HttpClient.PostAsync文件上传?
Posted
技术标签:
【中文标题】网络条件差时如何处理文件HttpClient.PostAsync文件上传?【英文标题】:How to handle file HttpClient.PostAsync file upload under poor network conditions? 【发布时间】:2015-03-04 18:04:08 【问题描述】:我正在开发一个以将多张照片上传到 Web api 为中心的移动应用程序。我正在使用 Xamarin.Forms 和 System.Net.Http.HttpClient 以及 Clumsy 来模拟糟糕的网络条件(滞后、丢包、无序数据包)。该应用程序最初是用 Titanium 编写的,对大多数用户来说运行良好,但一些移动网络较差的用户经常出现错误。展望未来,我们将移植到 Xamarin 并尝试适应连接性较差的用户。
using (var httpClient = CreateClient())
httpClient.Timeout = TimeSpan.FromMinutes(5);
using (var formData = new MultipartFormDataContent())
// add required fields via formData.Add() ...
var httpContent = new ByteArrayContent(imageData);
formData.Add(httpContent, "file", Guid.NewGuid() + ".jpg");
try
var response = await httpClient.PostAsync("fileupload", formData).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
responseObject = await ResponseMessageToResponseModel(response).ConfigureAwait(false);
catch (HttpRequestException ex)
Debug.WriteLine("HttpRequestException");
catch (TaskCanceledException ex)
Debug.WriteLine("TaskCanceledException");
然而,我发现在正常条件下一切正常;当使用“滞后、丢弃、乱序”启用 Clumsy 并尝试上传时,PostAsync() 永远不会完成并最终因 TaskCanceledException 而超时。奇怪的是文件最终在服务器上。所以 POST 数据显然可以通过。
我猜测服务器响应中丢弃的数据包意味着 HttpClient 永远不会收到正确的响应并继续等待直到超时。
直截了当,我想知道是否有人对如何使这个过程尽可能防弹有任何想法。如果文件第一次通过,那么仅仅抓住超时并再次尝试就不会很好地工作。有什么想法吗?
此外,任何有关 HttpClient 如何处理丢弃/无序数据包的信息,以便我更好地了解正在发生的事情也会很棒。
【问题讨论】:
我做了一些额外的测试,发现了一些有趣的东西。启用 Clumsy(传入和传出)如果我保持启用状态,我会得到最初描述的情况(文件成功上传,但 PostAsync 超时并抛出 TaskCanceledException)。但是,如果我在几分钟后关闭 Clumsy,那么一切都会成功。这是否意味着来自 web api 服务器的响应会一遍又一遍地发送,直到收到确认? 【参考方案1】:不久前我对 HttpClient 的一件事是对 POST 请求的特殊(读取不常见)处理。
发送 POST 请求时,它首先将标头(包括 ContentLenght
和特殊的 Expect: 100-continue
标头)发送到服务器,但没有正文。如果请求可以接受,则等待服务器响应状态码 100。之后,它开始发送身体。
此处的附加信息:
MSDN Page for ServicePointManager.Expect100Continue
MSDN blog post with some details
在我的情况下,问题是当请求大小太大而无法处理时,我正在与之交谈的后端服务(Play 框架)没有很好地处理协议的这一部分。它没有返回任何错误。并且请求只是超时了。所以禁用它
ServicePointManager.Expect100Continue = false;
在向该主机发送 任何 请求之前就为我解决了这个问题。至少现在它正在返回一些东西。
如果这没有帮助,我可以推荐的最好的方法是使用 wireshark 或类似的东西来查看电线上发生的事情。前提是它与您正在使用的这个 Clumsy 工具配合得很好。 (顺便谢谢你的链接。我自己也在找这样的东西)
【讨论】:
以上是关于网络条件差时如何处理文件HttpClient.PostAsync文件上传?的主要内容,如果未能解决你的问题,请参考以下文章