Unity WebGL UnityWebRequest 坏的请求数据

4
我有一个Unity游戏托管在一个Web发布平台上。该游戏连接到多个API,包括Microsoft PlayFab、Google Analytics和我们自己的后端服务器。有时(非常罕见,少于0.1%的时间)游戏无法连接到这些服务之一,我不确定原因。我从未能够在本地重现此问题。由于其罕见性,我们目前尚未能将其隔离到特定区域。它似乎影响特定的计算机/家庭。运行游戏的同一计算机上的多个浏览器将以相同的方式失败。有时,同一家庭中的多台计算机也会受到影响。
Microsoft和Google都返回400错误,并且我们自己的服务会回复400。Unity指出,UnityWebRequest期间发生了“未知错误”。
我无法查看与Microsoft或Google发送/接收的数据,但我可以查看我们自己的服务器日志,情况变得奇怪。UnityWebRequest成功到达我们的服务,该服务托管在AWS上并由CloudFlare代理。URL是正确的,但请求正文似乎完全奇怪:
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000xך\u0000\u0000\u0000\u0000\u0000`ך\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000`ך\u0000!\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"

这是请求体的内容。如果我获取字节(假设是UTF8编码的字符串),那么我得到以下结果:

byte[72] { 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 120, 215, 154, 0, 0, 0, 0, 0, 96, 215, 154, 0, 239, 191, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 215, 154, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

我的第一个猜测是,AWS/CloudFlare/Google可能被某些防火墙或地区屏蔽了,但如果确实是这种情况,我不会期望任何东西能够到达我们自己的 AWS 服务器进行分析。所以现在我不确定......

以下是相关 Unity(2018.2.21f1)代码:

UnityWebRequest www = UnityWebRequest.Post(uri, body);
UploadHandlerRaw uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body));
uploadHandler.contentType = "application/json";
www.uploadHandler = uploadHandler;
www.SetRequestHeader("Content-Type", "application/json");

yield return www.Send();

if (www.isNetworkError || www.isHttpError)
{
    Log(ELoggingLevel.Error, "Error while sending data: [{0}]", www.error);
}
else
{
    var contents = www.downloadHandler.text;
    // do useful stuff here
}

记录器确实被触发,因此isNetworkError或isHttpError为true。
[错误]: 发送数据时发生错误:[未知错误]
有人对发生了什么有任何想法吗? 有人认出服务器记录的那些数据吗?似乎我的Unity游戏会在某些罕见情况下拒绝发送任何合理的数据。
编辑:我在服务器上记录了内容类型,并且正在正确地获取application/json,这表明大部分数据已经正确到达。 多个用户的正文数据也是相同的。Unity可能只返回错误,因为服务器返回400。
2个回答

2
我曾经也遇到过同样的错误。我的应用程序客户偶尔会收到400或未知错误。但是我在本地无法重现这个问题。不过这个错误并不是由上传引起的,而是由多个(不同的)POST请求引起的。我使用的服务器提供商与你不同。
我试图找出原因和答案,但是一直找不到。
不过我成功地创建了一个解决方案/变通方法。似乎如果你延迟0.1秒执行相同的操作,它就可以顺利通过。所以我建议实施以下内容。
int tryCounts = 3;

for (int i = 0; i < tryCounts; i++)
{
    UnityWebRequest www = UnityWebRequest.Post(uri, body);
    UploadHandlerRaw uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body));
    uploadHandler.contentType = "application/json";
    www.uploadHandler = uploadHandler;
    www.SetRequestHeader("Content-Type", "application/json");

    yield return www.Send();

    if (www.isNetworkError || www.isHttpError)
    {
        Log(ELoggingLevel.Error, "Error while sending data: [{0}]", www.error);
        yield return new WaitForSecondsRealtime(0.15f); 
    }
    else
    {
        var contents = www.downloadHandler.text;
        // do useful stuff here
        break;
    }
}

这个简单的解决方案解决了我的所有问题。我仍然会看到一个未知错误从时间到时间地弹出在我的数据库错误日志中。由于我还记录了trycount,我可以确认它从未连续弹出两次。

非常有趣!我的也是一个POST请求。这只影响你的WebGL游戏副本,还是独立构建也受到影响(假设你也在使用Unity)?我会尝试一下并回报结果。谢谢。 - Giawa
哦,对不起,我的应用程序没有使用上传处理程序。我没有WebGL版本,我有使用Unity的Android / iOS构建版本。我相当确定这与UnityWebRequest有关,但是找不到任何官方来源。 - Immorality
我们最终找到了问题的根源,所以看起来我们可能遇到了不同的问题。很高兴听到你的解决方案对你有用,感谢你查看这个问题 :) - Giawa
确实听起来像是不同的问题。很高兴听到您已经解决了它。 - Immorality

1
这个问题是由杀毒软件引起的。我们发现受影响的用户使用的是卡巴斯基杀毒软件,具体来说是 '在流量中集成与网站交互的脚本' 功能,在 '流量处理' 选项卡下。我不知道为什么卡巴斯基认为这是一个合理的事情,我想它一定会破坏更多的东西,但就是这样。用户可以在卡巴斯基中禁用该选项,UnityWebRequest 就会像正常情况下一样运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接