c# - 网络不好的情况下如何处理文件HttpClient.PostAsync文件上传?

标签 c# xamarin httpclient

我正在开发一个以将多张照片上传到网络 API 为中心的移动应用程序。我正在使用 Xamarin.Forms 和 System.Net.Http.HttpClient,以及 Clumsy模拟较差的网络条件(滞后、丢包、无序数据包)。该应用程序最初是用 Titanium 编写的,对大多数用户来说运行良好,但移动网络较差的一些用户经常遇到错误。展望 future ,我们将移植到 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 如何处理丢弃/无序数据包的信息,以便我更好地理解正在发生的事情,这也是很好的。

最佳答案

HttpClient 的一件事是我刚才撞到头的是对 POST 请求的特殊(不常见)处理。 当发送 POST 请求时,它首先将 header (包括 ContentLenght 和特殊的 Expect: 100-continue header )发送到服务器但没有正文。如果请求可以接受,则等待服务器以状态码 100 响应。之后它开始发送 body 。 附加信息在这里: MSDN Page for ServicePointManager.Expect100Continue MSDN blog post with some details

在我的例子中,问题是当请求大小太大而无法处理时,我正在与之交谈的后端服务(Play 框架)没有很好地处理协议(protocol)的这一部分。它没有返回任何错误。请求只是超时了。所以禁用它 ServicePointManager.Expect100Continue = false; 在向该主机发送任何 请求之前,我已经解决了这个问题。至少现在它正在返回一些东西。

如果这没有帮助,那么我可以推荐的最好的方法是使用 wireshark 或类似的东西来查看线路上发生的事情。只要它与您正在使用的这个笨拙的工具配合得很好。 (顺便感谢链接。我自己也在寻找这样的东西)

关于c# - 网络不好的情况下如何处理文件HttpClient.PostAsync文件上传?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28861643/

相关文章:

Angular 4 新的 HttpClient 内容配置 header

C# 缺乏静态继承——我该怎么办?

c# - Xamarin iOS - 基于配置文件的代码

c# - WPF MVVM - 如何检测 View 是否为 "Dirty"

ios - 更改日期选择器的样式

c# - 在同一 View Controller 中添加 Collection View 和 TableView - Xamarin iOS

java - 使用 Http-Client 上传大文件

java - 尝试运行 jar 时出现 HttpClient java.lang.NoSuchMethodError

C# 捕获异常

c# - 无法将字符串解析为整数值