检查来自 Unity 的互联网连接

本文关键字:互联网 连接 Unity 检查 | 更新日期: 2023-09-27 18:25:56

我有一个为Android和iOS平台构建的Unity项目。我想检查桌面、安卓和 iOS 设备上的互联网连接。我读过三种不同的解决方案:

  1. ping一些东西(例如谷歌( - 我完全不喜欢这样的决定,而且我已经读过Android上的错误。

  2. Application.internetReachability - 根据 Unity 的文档,此函数只会确定我是否有连接到互联网的可能性(它不保证真正的连接(。

  3. Network.TestConnection() - 如果我没有互联网连接,我的应用程序将失败。所以这也不正确。

如何确定我是否在 Unity 中具有互联网连接?

检查来自 Unity 的互联网连接

我实际上并不认为Network.TestConnection()是这项工作的正确工具。根据文档,在我看来,它似乎是为了测试NAT是否正常工作以及您的客户端是否可以通过IP公开访问,但是您要检查的是您是否具有一般的互联网连接。

这是我在Unity pixel_fiend Answers上找到的一个解决方案,它只是测试一个网站,看看用户是否有连接。此代码的一个好处是它使用 IEnumerator 进行异步操作,因此连接测试不会阻碍应用程序的其余部分:

IEnumerator checkInternetConnection(Action<bool> action){
     WWW www = new WWW("http://google.com");
     yield return www;
     if (www.error != null) {
         action (false);
     } else {
         action (true);
     }
 } 
 void Start(){
     StartCoroutine(checkInternetConnection((isConnected)=>{
         // handle connection status here
     }));
 }

您可以将网站更改为您想要的任何内容,甚至可以修改代码以返回成功(如果可以访问多个站点中的任何一个(。AFAIK 如果不尝试连接到互联网上的特定站点,就无法检查真正的互联网连接,因此像这样"ping"一个或多个网站可能是您确定连接性的最佳选择。

public static IEnumerator CheckInternetConnection(Action<bool> syncResult)
{
    const string echoServer = "http://google.com";
    bool result;
    using (var request = UnityWebRequest.Head(echoServer))
    {
        request.timeout = 5;
        yield return request.SendWebRequest();
        result = !request.isNetworkError && !request.isHttpError && request.responseCode == 200;
    }
    syncResult(result);
}
void Start()
{
    StartCoroutine(CheckInternetConnection(isConnected =>
    {
        if (isConnected)
        {
            Debug.Log("Internet Available!");
        }
        else
        {
            Debug.Log("Internet Not Available");
        }
    }));
}
IEnumerator CheckInternetConnection(Action<bool> action)
{
    UnityWebRequest request = new UnityWebRequest("http://google.com");
    yield return request.SendWebRequest();
    if (request.error != null) {
        Debug.Log ("Error");
        action (false);
    } else{
        Debug.Log ("Success");
        action (true);
    }
}

由于 WWW 已被弃用,因此可以使用 UnityWebRequest 来代替。

我知道

这很旧,但也许可以帮助你。

public bool CheckInternetConnection(){
    return !(Application.internetReachability == NetworkReachability.NotReachable)
}

ping 8.8.8.8 而不是发送 GETUnity 已经为此提供了工具:

ping

操作是异步的,可以轮询 ping 对象状态使用 Ping.isDone。收到响应时,它位于平时间.

Windows 应用商店应用:流套接字用于模拟 ping功能,它将尝试打开与指定 IP 的连接使用端口 80 的地址。为了正常工作,互联网客户端必须在 Package.appxmanifest 中启用功能。

Android:ICMP套接字用于ping操作,如果它们是可用,否则 Unity 会生成一个子进程/system/bin/ping平操作。要检查 ICMP 套接字是否可用,您需要阅读/proc/sys/net/IPv4/ping_group_range 的内容。如果 ICMP套接字可用,此文件应包含 0 的条目2147483647。

using UnityEngine;
using System.Collections.Generic;
 
public class PingExample : MonoBehaviour
{
    bool isConnected = false;
    private IEnumerator Start()
    {
        while(true)
        {
            var ping = new Ping("8.8.8.8");
 
            yield return new WaitForSeconds(1f);
            while (!ping.isDone) 
            {
                isConnected = false;
                yield return null;
            }
            isConnected = true;
            Debug.Log(ping.time);
        }
    }
}

我创建了一个Android的库,可以用作Unity的插件。如果有人感兴趣,可以在 https://github.com/rixment/awu-plugin

至于iOS版本,不幸的是,我在这方面没有足够的知识。如果有人可以扩展存储库以包含iOS版本,那就太好了。

在最新版本的Unity中,WWW已经过时,因此您需要使用WebRequest。

这是我用来检查用户是否在线的代码:

private string HtmlLookUpResult_Content;
private char[] HtmlLookUpResult_Chars;
private StreamReader HtmlLookUpResult_Reader;
private bool HtmlLookUpResult_isSuccess;
private HttpWebRequest HtmlLookUpResult_Request;
private HttpWebResponse HtmlLookUpResult_Response;
public bool CheckIfOnline()
{
    HtmlLookUpResult_Content = UniversalEnum.String_Empty;
    HtmlLookUpResult_Request = (HttpWebRequest)WebRequest.Create(UniversalEnum.WebHtml_isOnline);
    HtmlLookUpResult_Request.Timeout = 5000;
    try
    {
        using (HtmlLookUpResult_Response = (HttpWebResponse)HtmlLookUpResult_Request.GetResponse())
        {
            HtmlLookUpResult_isSuccess = (int)HtmlLookUpResult_Response.StatusCode < 299 && (int)HtmlLookUpResult_Response.StatusCode >= 200;
            if (HtmlLookUpResult_isSuccess)
            {
                using (HtmlLookUpResult_Reader = new StreamReader(HtmlLookUpResult_Response.GetResponseStream()))
                {
                    HtmlLookUpResult_Chars = new char[1];
                    HtmlLookUpResult_Reader.Read(HtmlLookUpResult_Chars, 0, 1);
                    HtmlLookUpResult_Content += HtmlLookUpResult_Chars[0];
                }
            }
        }
    }
    catch
    {
        HtmlLookUpResult_Content = UniversalEnum.String_Empty;
    }
    if (HtmlLookUpResult_Content != UniversalEnum.String_Empty)
    {
        return true;
    }
    else
    {
        return false;
    }
}

如果您想知道用户是否只是在线,则可以仅从代码中的布尔HtmlLookUpResult_isSuccess中获取结果。但是,实际上,您很可能希望确认用户也可以访问您的服务器或您在项目中使用的任何远程系统,对吗?这就是代码的其余部分的作用。

如果你想知道 UniversalEnum 是什么,在我的代码中,它是一个单独的非 Monobehavior 脚本,其中包含我计划在我的项目中重用的所有持久变量(如字符串和哈希(。简而言之:

UniversalEnum.String_Empty = ";

UniversalEnum.WebHtml_isOnline ="http://www。ENTER_YOUR_WEBSITE_HERE.com/游戏-latestnews/isOnline.html">

也就是说,正如你所看到的,即在线.html文件是我托管网站HTML_content的"games-latestnews"文件夹中的一个文件,它只包含[1]的内容。它没有标题,没有实际内容,几乎就像在线设置的.txt文件。我使用这种方法也是因为我可以通过在该文件夹中添加新的 HTML 页面来向我的游戏添加新新闻。我还用 Try{} 包围内容检查,以便如果任何失败,它会返回 Catch{} 值,然后通过比较内容(字符串(是空字符串还是包含任何内容,我们知道用户是否在线以及他/她是否可以访问您的网站。

为什么您要检查用户是否可以访问网络和您的网站的一个很好的例子是,如果用户使用的是有限的网络,例如您可能在学校找到的网络。如果学校出于任何原因决定禁止您的网站,只需查找连接是否可行就会返回误报,因为它无论如何都不会访问实际网页。

您可以使用

此代码检查网络连接

if(Application.internetReachability == NetworkReachability.NotReachable){
       Debug.Log("Error. Check internet connection!");
}