最近发现unity在ios平台使用UnityWebRequest会偶尔出现无响应的情况,明明发送了webRequest请求但一直卡住在请求的协程或者开异步进程的请求中,不会继续执行下去。而且这个问题只会在ios出现,在android或者pc平台是复现不了,一开始以为是自己代码的原因,但把请求从头到尾都debug输出过一遍后,发现代码是没错的,但web请求偶尔还是会卡住,即使设置了超时时间也一样。而且只要一出现这种情况,之后的webrequest请求都会卡在同一个地方。
附上代码:
public async UniTask DownloadSceneJsonRequest(string sceneId, string path)
{
Debug.Log("=========enter DownloadSceneJsonRequest");
var uri = new Uri(_domain + SceneApi + sceneId);
var uwr = new UnityWebRequest(uri, UnityWebRequest.kHttpVerbGET)
{
downloadHandler = new DownloadHandlerFile(path),
timeout=10,
useHttpContinue=false
};
Debug.Log("========= SendWebRequest+"+ _domain + SceneApi + sceneId);
await uwr.SendWebRequest();
//并没有以下输出
Debug.Log("========= complete SendWebRequest");
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log(uwr.error);
}
uwr.Dispose();
}
总的来概括这个问题就是:只在ios平台,使用unitywebrequest请求时,会偶发出现卡住webrequest请求无响应的情况,但没有必现规律,而且一旦出现,则后面的请求都会被阻断无响应。而且这跟unity的版本无关,在unity2019.3.0 unity2019.3.13 unity2019.4.19 unity2020.1.13都会出现一样的情况。
后面总算在unity的官方论坛中找到了一样的情况,而且都是使用了ARFoundation与UnityWebrequest,附上帖子的链接:UnityWebRequests on iOS sometimes get stuck indefinitely even with timeout set - Unity Forum
原来是两个原因导致了这种情况:
1.使用了ARFoundation
2.在高于ios14.1(不包括)版本上使用app
根据外国网友的反馈,ARFoundation的ARSession脚本也发送unitywebrequest请求,当AR在Tracking lost -> recovering这状态瞬间时就会出现webrequest无响应的状态,而且最重要的是:
这是Unity的一个Bug。
具体导致的原因牵扯到unity打开出xcode工程后里面UnityWebRequest.mm类的代码逻辑,因为我对xcode的webrequest请求原理不太熟悉,感兴趣的可以查看原帖里面其他开发者的讨论。
下面来说下解决方案:
在生成的XCode工程中找到UnityWebRequest.mm类,对里面的UnityCreateWebRequestBackend函数增加一行代码:
webOperationQueue = [[NSOperationQueue alloc] init];
webOperationQueue.name = @"com.unity3d.WebOperationQueue";
webOperationQueue.qualityOfService = NSQualityOfServiceUserInteractive;
同时对于使用Unity2018.4以下的版本的解决方案:
因为unity2018版还没有UnityWebRequest,使用的还是WWW,找到输出的Xcode工程中的WWWConnection.mm类,在第392行添加下面的代码:
webOperationQueue.qualityOfService = NSQualityOfServiceUserInteractive;
总结:虽然是找到了解决方案,但毕竟这是Unity的bug而且还比较致命,每次发布都需要在对应的类里面进行修改,希望Unity能早日修复这个bug。