Search Unity

Discussion Application.internetReachability works in Unity Editor in Windows but not in the Window Build

Discussion in 'Windows' started by exsurgo_ankit, May 10, 2023.

  1. exsurgo_ankit

    exsurgo_ankit

    Joined:
    Feb 5, 2020
    Posts:
    29
    Hello,

    I am using 2021.3.24f1 release and when I test my offline flow in the unity editor on the same Windows 10 machine, it works as expected.
    ie.
    Application.internetReachability == NetworkReachability.NotReachable is True when WiFi is disconnected or ethernet cable is unplugged.

    However the same test does not work in the Windows standalone build generated and run of the same machine.

    I reviewed this thread which is relevant to UWP but the workaround does not work for me
    https://forum.unity.com/threads/windows-uwp-application-internetreachability-broken.1064825/

    Is this a bug or is there another way to verify internet connectivity in the Windows standalone build?

    Regards
    Ankit
     
  2. TomTheMan59

    TomTheMan59

    Joined:
    Mar 8, 2021
    Posts:
    356
    Please do not use this to test actual connection!!!

    This property is mostly useful on handhelds to distinguish fast and cheap WiFi connection from carrier networking.

    Note: Do not use this property to determine the actual connectivity. E.g. the device can be connected to a hot spot, but not have the actual route to the network. Non-handhelds are considered to always be capable of NetworkReachability.ReachableViaLocalAreaNetwork.

    https://docs.unity3d.com/ScriptReference/Application-internetReachability.html

    You need to have your own server and test connection that way.
     
  3. exsurgo_ankit

    exsurgo_ankit

    Joined:
    Feb 5, 2020
    Posts:
    29
    Noted and thanks for highlighting the point. However, it works in the Unity Editor on the same machine. Hence it can be misleading.

    Is there an alternative or a work around?

    Regards
     
    TomTheMan59 likes this.
  4. exsurgo_ankit

    exsurgo_ankit

    Joined:
    Feb 5, 2020
    Posts:
    29
    I have implemented the following as a start.

    Note that I do not inherit from MonoBehaviour so I use a utility class GlobalCoroutineHost.
    Check this out for help
    https://answers.unity.com/questions/161084/coroutine-without-monobehaviour.html


    To use the class call
    Code (CSharp):
    1. //call this at the start of the application once
    2. CheckInternetConnectivity.Init();
    3.  
    4. //to check for internet call this
    5. CheckInternetConnectivity.IsDeviceConnectedToInternet()
    Code (CSharp):
    1. public static class CheckInternetConnectivity
    2.     {
    3.         /***
    4.          * In window standalone build Application.InternetReachability does not work.
    5.          * However, it works well enough in Android.
    6.          * Based on suggestions from this thread
    7.          * https://stackoverflow.com/questions/2031824/what-is-the-best-way-to-check-for-internet-connectivity-using-net         *
    8.          * Following has been implemented
    9.          * */
    10.  
    11.         private static volatile bool internetConnected;
    12.         private const int RECHECK_DELAY_SECONDS = 10;
    13.         private static string weburl = "www.google.com";
    14.  
    15.         public static void Init()
    16.         {
    17.             internetConnected = false;
    18.  
    19.             //initate a periodic check only for non handheld devices
    20. #if !(UNITY_ANDROID || UNITY_IOS || UNITY_TVOS)
    21.             weburl = CultureInfo.InstalledUICulture switch
    22.             {
    23.                 { Name: var n } when n.StartsWith("fa") => // Iran
    24.                     "http://www.aparat.com",
    25.                 { Name: var n } when n.StartsWith("zh") => // China
    26.                     "http://www.baidu.com",
    27.                 _ =>
    28.                     "http://www.google.com",
    29.             };
    30.  
    31.             //intiate the first check
    32.             GlobalCoroutineHost.StartRoutine(CheckWebConnectivity(new object(), 0));
    33. #endif
    34.         }
    35.  
    36.         public static bool IsDeviceConnectedToInternet()
    37.         {
    38. #if UNITY_ANDROID || UNITY_IOS || UNITY_TVOS
    39.             return Application.internetReachability != NetworkReachability.NotReachable
    40. #else
    41.             return internetConnected;
    42. #endif
    43.         }
    44.  
    45.  
    46.         /// <summary>
    47.         /// https://stackoverflow.com/a/23009713
    48.         /// This approach has been discussed in this response
    49.         /// </summary>
    50.         private static IEnumerator CheckWebConnectivity(object state, int delayinSeconds)
    51.         {
    52.             yield return null;
    53.          
    54.             //wait if requested
    55.             if(delayinSeconds > 0)
    56.             {
    57.                 yield return new WaitForSeconds(delayinSeconds);
    58.             }
    59.  
    60.             if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    61.             {
    62.                 using (WebClient webClient = new WebClient())
    63.                 {
    64.                     webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
    65.                     webClient.Proxy = null;
    66.                     webClient.OpenReadCompleted += webClient_OpenReadCompleted;
    67.                     webClient.OpenReadAsync(new Uri(weburl));
    68.                 }
    69.             }
    70.         }
    71.  
    72.      
    73.         private static void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    74.         {
    75.             if (e.Error == null)
    76.             {
    77.                 internetConnected = true;              
    78.             }
    79.             else
    80.             {
    81.                 internetConnected = false;
    82.             }
    83.  
    84.             //reschedule the check in a few seconds
    85.             GlobalCoroutineHost.StartRoutine(CheckWebConnectivity(sender, RECHECK_DELAY_SECONDS));
    86.         }
    87.     }