切换到IPV6时HttpClient抛出异常 - 从iOS Store拒绝

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了切换到IPV6时HttpClient抛出异常 - 从iOS Store拒绝相关的知识,希望对你有一定的参考价值。

我正在研究一个Xamarin项目的奇怪问题,我很难过......

我使用HTTPClient来发出异步请求。但是,我的应用程序因未能满足Apple的IPV6要求而被应用商店拒绝。也就是说,当通过IPV6连接时,我使用HTTPClient发出的请求失败。奇怪的是,只有当应用程序在IPV4网络上启动然后切换到IPV6网络时才会失败。如果我在连接到IPV6网络时重新启动应用程序,它会成功!此外,如果我启动连接到IPV6的应用程序然后切换到IPV4网络,它也会成功。它仅在IPV4中启动然后切换到IPV6时失败。

这非常奇怪 - 就像HttpClient缓存一样,但我们为每个请求创建一个新的客户端。我没有使用IP地址 - 只是一个地址,而且,正如我所提到的,当应用程序开始连接到仅IPV6网络时,它可以正常工作。它只是从IPV4到IPV6的转换,这似乎导致了这个问题。

PCL中存在的代码:

var client = new HttpClient();
var urlToCall = new Uri("https://www.something.com/someapi/v1");
// Add some headers
...
response = client.GetAsync(urlToCall);

并且堆栈跟踪:

Trace.Message": "Error: ConnectFailure (Network is unreachable)
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00065] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.ios.framework/Versions/git/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:946 
at System.Threading.Tasks.TaskFactory`1[TResult].FromAsyncCoreLogic (IAsyncResult iar, System.Func`2 endFunction, System.Action`1 endAction, System.Threading.Tasks.Task`1 promise, Boolean requiresSynchronization) <0x10019c730 + 0x0005b> in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () <0x10013ccc0 + 0x0001b> in <filename unknown>:0 
at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext () [0x003d6] in /Library/Frameworks/Xamarin.iOS.framework/Versions/9.6.1.9/src/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs:372 
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () <0x10013ccc0 + 0x0001b> in <filename unknown>:0 
at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000a9] in /Library/Frameworks/Xamarin.iOS.framework/Versions/9.6.1.9/src/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:274 
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 
at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () <0x10013c8c0 + 0x0001b> in <filename unknown>:0 
at MyApp.RestClient.RestService`2+<SendHttpRequest>d__10[TInput,TOutput].MoveNext () [0x00259] in <filename unknown>:0 
Network is unreachable
at System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP) [0x000bc] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net.Sockets/Socket.cs:1235 
at System.Net.WebConnection.Connect (System.Net.HttpWebRequest request) [0x001c2] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/WebConnection.cs:213 

以前有人见过这样的事吗?有没有人知道如何修复甚至调试这个?

答案

在iOS Build设置中,将HttpClient Implementation设置为使用NSURLSession

Link to Xamarin Documentation

默认值仍然是由HttpWebRequest提供支持的HttpClient,而您现在可以选择切换到使用iOS,tvOS或OS X的本机传输(NSUrlSession或CFNetwork,具体取决于操作系统)的实现。好处是较小的二进制文件,下载速度更快,缺点是它需要运行事件循环才能执行异步操作。

iOS Build Settings

您使用的是主机名,而不是硬编码的IPv4 IP地址,这是个好消息!如果您使用的是硬编码的IPv4 IP地址,Apple将拒绝您的应用。

确保检查主机名是否可以解析IPv6 IP地址。在System.Net.Dns中还有一些有用的方法可以帮助您解析IP地址,以便查看IPv6是否可用。

您也可以尝试使用.MapToIPv6()扩展方法:Link to MSDN documentation

另一答案

看看ModernHttpClient

Awesome explanation from the ModernHttpClient author.

它非常棒,我们将它与所有Xamarin.Forms项目一起使用。

附:

我们最新的iOS应用程序之一也最初被拒绝。

Here is how we solved IPV6 issue.

以上是关于切换到IPV6时HttpClient抛出异常 - 从iOS Store拒绝的主要内容,如果未能解决你的问题,请参考以下文章

C# HttpClient 在没有成功状态代码时抛出异常 [关闭]

HttpClient 可以抛出哪些异常?

C# HttpClient.SendAsync 在测试某些 URL 时抛出“发送请求时发生错误”异常

从调试模式切换到发布模式时,C# Asp.Net Webservice 抛出异常

解决httpclient抛出URISyntaxException异常

无限超时的 HttpClient 抛出超时异常