使用Httpclient的大型视频文件上传在Xamarin.Android上不起作用 [英] Large VIDEO File Upload using Httpclient does not work on Xamarin.Android
问题描述
任何帮助或见识将不胜感激.
Any Help or insight would be much appreciated.
我设法获得的是该问题与HTTPS有关,因为在发布到HTTP端点时我能够收到200的回扣,类似于以下线程
What I have managed to obtain is that the issue is related to HTTPS as I am able to receive a 200 back when posting to an HTTP endpoint, similar to the following thread here
当前很难解决以下问题:
Currently having a difficult time trying to resolve the following issue:
我将AndroidClientHandler HttpClient实现以及NativeTLS 1.2+用于SSL/TLS实现
I'm using the AndroidClientHandler HttpClient implementation as well as the NativeTLS 1.2+ for the SSL/TLS Implementation
当我在自己的应用中录制了超过1分钟或超过20MB的视频时,出现以下错误: 无法访问已处置的对象.\ n对象名称: 'System.Net.Sockets.NetworkStream'."
When I record a Video on my app that is longer than 1 min, or larger than 20MB I receive the following error: "Cannot access a disposed object.\nObject name: 'System.Net.Sockets.NetworkStream'."
这是方法
public async Task<HttpResponseMessage> UploadVideo(string endPoint)
{
HttpResponseMessage responseMessage = null;
try
{
//Stopwatch stopWatch = new Stopwatch();
IList<KeyValuePair<string, string>> formFields = new List<KeyValuePair<string, string>>();
messageHandlerService = Mvx.Resolve<IMessageHandlerService>();
//Declare a scope whereby you can use resources and once you leave the scope the resources are disposed of.
using (StreamReader reader = pathService.GetStreamReaderByPlatform())
{
client = await MyHttpClient.GetClientAsync();
client.Timeout = TimeSpan.FromSeconds(500);
var bytes = default(byte[]);
using (var memstream = new MemoryStream())
{
reader.BaseStream.CopyTo(memstream);
bytes = memstream.ToArray();
using (var content = new MultipartFormDataContent())
{
var fileContent = new ByteArrayContent(bytes);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = ".mp4",
};
content.Add(fileContent);
content.Add(EncodeFields(formFields));
await Policy.Handle<TimeoutException>()
.Or<HttpRequestException>()
.Or<IOException>()
.OrResult<HttpResponseMessage>(r => httpStatusCodesToRetry.Contains(r.StatusCode))
.WaitAndRetryAsync
(retryCount: 3,
sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
onRetry: (ex, time) =>
{
Debug.WriteLine($"Something went wrong: {ex.Exception.Message}, retrying...");
}).ExecuteAsync(async () =>
{
Debug.WriteLine($"Trying to fetch remote data...");
responseMessage = await client.PostAsync(endPoint, content);
return responseMessage;
});
}
}
}
}
catch (WebException webx)
{
if (responseMessage == null)
{
responseMessage = new HttpResponseMessage();
}
responseMessage.StatusCode = HttpStatusCode.InternalServerError;
responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", webx);
}
catch (Exception ex)
{
if (responseMessage == null)
{
responseMessage = new HttpResponseMessage();
}
responseMessage.StatusCode = HttpStatusCode.InternalServerError;
responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", ex);
}
return responseMessage;
}
下面是堆栈跟踪:
Below is the Stack Trace:
"位于System.Net.WebConnectionStream.EndWrite(System.IAsyncResult r)[0x000b8],位于< 5a97d41d36694fb19855c17429527b10>:0 \ n,位于System.IO.Stream +<> c.b__53_1(System.IO.Stream流,System.IAsyncResult asyncResult)[0x00000]在(包装委托调用)System.Func 3[System.IO.Stream,System.IAsyncResult,System.Threading.Tasks.VoidTaskResult].invoke_TResult_T1_T2(System.IO.Stream,System.IAsyncResult)\n at System.Threading.Tasks.TaskFactory
1 + FromAsyncTrimPromise 1[TResult,TInstance].Complete (TInstance thisRef, System.Func
3 [T1,T2,TResult]上为0 \ n,endMethod,System.IAsyncResult asyncResult,System.布尔值requireSynchronization)在:0中的[0x00000] \ n ---从上一次引发异常的位置开始的堆栈跟踪--- \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()中在[0x0000c]在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)[0x00028]上,位于System \\ Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task任务)[0x0003e] ],位于System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd::0 \ n中(System.Threading.Tasks.Task任务)[0x00008]位于System.Runtime.Compi,位于:0 \ n lerServices.ConfiguredTaskAwaitable + ConfiguredTaskAwaiter.GetResult()[0x00000]在System.Net.Http.MultipartContent + d__8.MoveNext()在<996a681f30a44cd685a4da54e11956e2>:0的\ n中:: 0 \ n--堆栈跟踪结束从之前引发异常的位置开始--- \ n在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task task)中的[0x0003e] [0x0003e](System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System.Threading.Tasks.Task task)[0x00028] in:0 \ n .Threading.Tasks.Task任务)[0x00008]在System.Runtime.CompilerServices.ConfiguredTaskAwaitable + ConfiguredTaskAwaiter.GetResult()在:0 \ n在System.Net.Http.HttpClientHandler + d__64.MoveNext ()[0x0036e]在< 996a681f30a44cd685a4da54e11956e2>:0 \ n --- previ中的堆栈跟踪结束在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处抛出异常的位置--- \ n,在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task任务:0 \ n处为[0x0000c] )[0x0003e]在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)的[0x00028]在[\ 0.n.System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System. Threading.Tasks.Task任务)[0x00008]在System.Runtime.CompilerServices.ConfiguredTaskAwaitable 1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Net.Http.HttpClient+<SendAsyncWorker>d__49.MoveNext () [0x000ca] in <996a681f30a44cd685a4da54e11956e2>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter
1处为:0 \ n
…
" at System.Net.WebConnectionStream.EndWrite (System.IAsyncResult r) [0x000b8] in <5a97d41d36694fb19855c17429527b10>:0 \n at System.IO.Stream+<>c.b__53_1 (System.IO.Stream stream, System.IAsyncResult asyncResult) [0x00000] in :0 \n at (wrapper delegate-invoke) System.Func3[System.IO.Stream,System.IAsyncResult,System.Threading.Tasks.VoidTaskResult].invoke_TResult_T1_T2(System.IO.Stream,System.IAsyncResult)\n at System.Threading.Tasks.TaskFactory
1+FromAsyncTrimPromise1[TResult,TInstance].Complete (TInstance thisRef, System.Func
3[T1,T2,TResult] endMethod, System.IAsyncResult asyncResult, System.Boolean requiresSynchronization) [0x00000] in :0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0 \n at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0 \n at System.Net.Http.MultipartContent+d__8.MoveNext () [0x0025d] in <996a681f30a44cd685a4da54e11956e2>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0 \n at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0 \n at System.Net.Http.HttpClientHandler+d__64.MoveNext () [0x0036e] in <996a681f30a44cd685a4da54e11956e2>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0 \n at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Net.Http.HttpClient+<SendAsyncWorker>d__49.MoveNext () [0x000ca] in <996a681f30a44cd685a4da54e11956e2>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter
1
…
推荐答案
我已经通过在Xamarin.Android的项目构建设置"中设置一些标志来解决了该问题.
I have resolved the issue by setting some flags in the Project Build Settings within Xamarin.Android.
与文档相反建议,通过设置以下配置,我可以使用HTTPS将文件发布到我的服务器上.在使用本机TLS 1.2+时,大于20MB的上传会崩溃...是的,我们的服务器支持TLS 1.2
Contrary to what the Docs suggest, setting the following configuration allows for me to POST the file to my server using HTTPS. While using the Native TLS 1.2+ crashes on uploads larger than 20MB...yes our server supports TLS 1.2
这篇关于使用Httpclient的大型视频文件上传在Xamarin.Android上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!