【问题标题】:WWW freezing when there is no internet没有互联网时WWW冻结
【发布时间】:2018-02-22 11:08:24
【问题描述】:

我正在 Unity 中编写一个简单的代码,以检查我是否能够通过我的应用访问网站。这是我写的代码:

IEnumerator CheckInternetPing()
{
    WWW wwwInternet = new WWW("http://google.com");
    yield return wwwInternet;
    if (wwwInternet.bytesDownloaded == 0)
    {
        //yield return new WaitForSeconds(1f);
        Debug.Log("Not Connected to Internet");
    }
    else
    {
        Debug.Log("Connected to Internet");
        internetMenu.SetActive(false);
    }
}

我发现了一个错误,如果我在 Internet 上运行此程序,它会显示“已连接”,但是当我关闭 Internet 并立即运行该应用程序时,它不会记录任何内容。只有当我再次重新启动应用程序时,它才会显示“未连接”。 有谁知道为什么它在第一次没有记录?谢谢

【问题讨论】:

  • 多少次显示“已连接”??
  • 实际连接时只有1次
  • 代码只输入一次......你需要更频繁地调用它,放置一个计时器并调用它
  • 您使用的是哪个版本?使用 2017.3.0f3 我无法重现该错误,代码工作正常。
  • 我用的是同一个版本。我是否使用飞行模式来打开/关闭互联网是否重要?

标签: c# unity3d httprequest


【解决方案1】:

这是WWW 类的错误,已经存在很长时间了。每个设备的行为可能都不同。如果 Wifi 被禁用,它曾经在编辑器上冻结。快速测试表明此错误尚未修复。

您需要使用HttpWebRequest 而不是WWW

在下面的示例中,Thread 用于避免请求阻塞 Unity 程序,UnityThread 用于在请求完成时回调到 Unity 主线程。从this 帖子中获取UnityThread

void Awake()
{
    //Enable Callback on the main Thread
    UnityThread.initUnityThread();
}

void isOnline(Action<bool> online)
{
    bool success = true;

    //Use ThreadPool to avoid freezing
    ThreadPool.QueueUserWorkItem(delegate
    {
        try
        {
            int timeout = 2000;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://google.com");
            request.Method = "GET";
            request.Timeout = timeout;
            request.KeepAlive = false;

            request.ServicePoint.Expect100Continue = false;
            request.ServicePoint.MaxIdleTime = timeout;

            //Make sure Google don't reject you when called on mobile device (Android)
            request.changeSysTemHeader("User-Agent", "Mozilla / 5.0(Windows NT 10.0; WOW64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 55.0.2883.87 Safari / 537.36");

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if (response == null)
            {
                success = false;
            }

            if (response != null && response.StatusCode != HttpStatusCode.OK)
            {
                success = false;
            }
        }
        catch (Exception)
        {
            success = false;
        }

        //Do the callback in the main Thread
        UnityThread.executeInUpdate(() =>
        {
            if (online != null)
                online(success);
        });

    });
}

您需要 changeSysTemHeader 函数的扩展类,它允许更改 "User-Agent" 标头:

public static class ExtensionMethods
{
    public static void changeSysTemHeader(this HttpWebRequest request, string key, string value)
    {
        WebHeaderCollection wHeader = new WebHeaderCollection();
        wHeader[key] = value;

        FieldInfo fildInfo = request.GetType().GetField("webHeaders",
                                                System.Reflection.BindingFlags.NonPublic
                                                   | System.Reflection.BindingFlags.Instance
                                                   | System.Reflection.BindingFlags.GetField);

        fildInfo.SetValue(request, wHeader);
    }
}

使用起来真的很简单:

void Start()
{
    isOnline((online) =>
    {
        if (online)
        {
            Debug.Log("Connected to Internet");
            //internetMenu.SetActive(false);
        }
        else
        {
            Debug.Log("Not Connected to Internet");
        }
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多