Unity中CognitoAWSCredentials首次调用延迟问题求助
解决Unity 2022 LTS中CognitoAWSCredentials调用S3首次请求延迟问题(强制IPv4)
问题根源
你的场景中,CognitoAWSCredentials首次请求延迟的核心原因是:DNS解析优先尝试IPv6,但网络环境不支持IPv6,导致请求超时后回退到IPv4。BasicAWSCredentials无需通过Cognito获取临时凭证,跳过了这一解析流程,因此无延迟。
兼容Unity 2022 LTS的解决方案
Unity 2022 LTS基于.NET Standard 2.1,无法使用依赖SocketsHttpHandler的配置,以下是适配旧版HTTP栈的可行方案:
方案1:全局设置ServicePointManager强制IPv4
Unity的HTTP请求依赖System.Net.ServicePointManager,可以通过配置让所有请求优先使用IPv4:
using System.Net; using UnityEngine; public class AWSIPv4Setup : MonoBehaviour { void Awake() { // 缩短DNS刷新超时,加快回退速度 ServicePointManager.DnsRefreshTimeout = 1000; // 确保TLS版本兼容AWS服务 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // 遍历AWS相关服务节点,强制使用IPv4 foreach (ServicePoint sp in ServicePointManager.FindServicePoints(new Uri("https://*.amazonaws.com"))) { sp.ConnectionLeaseTimeout = 60000; // 1分钟后释放连接,避免旧连接复用 sp.AddressFamily = AddressFamily.InterNetwork; // 指定仅使用IPv4 } } }
将此脚本挂载到场景初始化GameObject上,确保在AWS客户端初始化前执行。
方案2:自定义AWS端点解析器(针对Cognito和S3)
为AWS客户端配置自定义IEndpointResolver,强制将AWS域名解析为IPv4地址:
using Amazon; using Amazon.CognitoIdentity; using Amazon.S3; using System.Linq; using System.Net; using System.Net.Sockets; public class AWSIPv4Resolver : IEndpointResolver { private readonly IEndpointResolver _originalResolver; public AWSIPv4Resolver(IEndpointResolver originalResolver) { _originalResolver = originalResolver; } public Endpoint ResolveEndpoint(RegionEndpoint region, string serviceName) { var endpoint = _originalResolver.ResolveEndpoint(region, serviceName); // 解析域名,筛选出IPv4地址 var ipAddresses = Dns.GetHostAddresses(endpoint.Hostname); var ipv4Address = ipAddresses.First(ip => ip.AddressFamily == AddressFamily.InterNetwork); // 替换为IPv4地址构建新端点 return new Endpoint { Hostname = ipv4Address.ToString(), Port = endpoint.Port, Protocol = endpoint.Protocol, RegionEndpoint = region }; } } // 初始化AWS客户端时应用自定义解析器 public void InitializeAWSClient() { var targetRegion = RegionEndpoint.USEast1; // 替换为你的实际区域 var originalResolver = new DefaultEndpointResolver(); var ipv4Resolver = new AWSIPv4Resolver(originalResolver); // 初始化Cognito客户端 var cognitoConfig = new AmazonCognitoIdentityConfig { RegionEndpoint = targetRegion, EndpointResolver = ipv4Resolver }; var cognitoClient = new AmazonCognitoIdentityClient(cognitoConfig); // 初始化带Cognito凭证的S3客户端 var cognitoCredentials = new CognitoAWSCredentials( "your-identity-pool-id", targetRegion, cognitoClient ); var s3Config = new AmazonS3Config { RegionEndpoint = targetRegion, EndpointResolver = ipv4Resolver }; var s3Client = new AmazonS3Client(cognitoCredentials, s3Config); }
注意:此方法需确保AWS服务的IPv4地址不会频繁变更,若AWS更新端点,需重新解析地址。
方案3:针对不同平台设置环境变量
- Unity编辑器:通过启动脚本设置环境变量:
using UnityEngine; using System; [InitializeOnLoad] public static class EditorIPv4Setup { static EditorIPv4Setup() { Environment.SetEnvironmentVariable("DOTNET_SYSTEM_NET_DISABLEIPV6", "1"); } } - Android:在
AndroidManifest.xml中添加meta-data:<application> <meta-data android:name="DOTNET_SYSTEM_NET_DISABLEIPV6" android:value="1" /> </application> - iOS:在
Info.plist中添加环境变量配置:<key>EnvironmentVariables</key> <dict> <key>DOTNET_SYSTEM_NET_DISABLEIPV6</key> <string>1</string> </dict>
此方法直接禁用IPv6,和你之前测试的效果一致,但需注意部分平台(如iOS App Store)可能对IPv6有强制要求,需根据实际场景选择。
验证建议
- 优先测试方案1,全局配置实现简单,对所有AWS请求生效;
- 若方案1无效,尝试方案2,针对性解析AWS端点;
- 环境变量方案作为兜底,但需考虑平台兼容性限制。
内容的提问来源于stack exchange,提问作者Eduardo Coelho
相关产品推荐
相关产品推荐

