Search Unity

How can you tell if there exists a network connection of any kind ?

Discussion in 'Multiplayer' started by paulsz, Nov 29, 2010.

  1. paulsz

    paulsz

    Joined:
    Mar 25, 2010
    Posts:
    29
    To be more specific, how can one be sure to use the methods of classes like Network (Connect, InitializeServer, etc ) when there is no LAN, Wifi or ethernet connection ?

    In this case (where no connection is available on the target device) nasty errors occur when trying to Initialize a server or to poll for a host list.

    The more general question would be how can one manage in code this type of situation ?

    Try catch statements don't help because for example Network.Connect() makes the device connect only after a while so the error "Cannot resolve connection tester address, you must be connected to the internet before performing this or set the address to something accessible to you" pops out after the code in the try block has executed as normal.

    I think the solution is implementing some sort of polling system that checks in every frame if there is a network connection since this information is critical for any operations with the Network so it has to be as up-to-date as possible.

    I have found (on this forum) a not so satisfying solution that constantly checks if there is internet availability.

    The code is bellow, if anyone wants to use it:


    Code (csharp):
    1. bool thereIsConnection = false;
    2. IEnumerator TestConnection()
    3.     {
    4.  
    5.  
    6.         float timeTaken = 0.0F;
    7.         float maxTime = 2.0F;
    8.  
    9.         while ( true )
    10.         {
    11.             Ping testPing = new Ping( "74.125.79.99" );
    12.  
    13.             timeTaken = 0.0F;
    14.  
    15.             while ( !testPing.isDone )
    16.             {
    17.  
    18.                 timeTaken += Time.deltaTime;
    19.  
    20.  
    21.                 if ( timeTaken > maxTime )
    22.                 {
    23.                     // if time has exceeded the max
    24.                     // time, break out and return false
    25.                     thereIsConnection = false;
    26.                     break;
    27.                 }
    28.  
    29.                 yield return null;
    30.             }
    31.             if ( timeTaken <= maxTime ) thereIsConnection = true;
    32.             yield return null;
    33.         }
    34.     }
    This Coroutine Pings the www.google.com address and checks for a response. This works well in determining whether or not one has internet access but this condition is not allways valid since wifi networks can be local, withoug access to the internet and games can still be played in such networks (ex: for iPhone - it can detect a wifi network with no internet access but it can still play wifi games with locally connected devices in that network... i think :confused: )

    My game is for the iPhone so I guess another approach would be to code smth directly in XCode but I would really appreciate it if there would be a more elegant, accessible and C-sharpy solution to this :)

    Any help would be awesome,

    Thx alot, guys.

    Paul
     
  2. spire8989

    spire8989

    Joined:
    Aug 18, 2010
    Posts:
    94
    Does this command not work?

    iPhoneNetworkReachability.ReachableViaWiFiNetwork
     
  3. paulsz

    paulsz

    Joined:
    Mar 25, 2010
    Posts:
    29
    Thanks for the answer spire,

    I knew about this function from iPhoneSettings.internetReachability but it didn't work when I was testing with the Unity editor - it returned Reachable allways even if there wasn't actually any wifi available.

    I realized that it only worked when I installed it on the device since the class name is iPhoneSettings, not UnityEditorSettings :)

    So, this solves my problem for now but I am eager to know a way to generally detect wifi networks regardless of the device it is installed on (web player, android or xbox) since I want my game to be played on multiple platforms.

    This type of issue was dealt with very elegantly by Unity when they deprecated the class iPhoneTouch and made the general class Touch.

    Thx again for the help,
    Paul
     
  4. iceshaft07

    iceshaft07

    Joined:
    Jul 23, 2010
    Posts:
    293
    One way you could do that is simply ping the master server, and if you get a response back, than you *should* be connected ;-)
     
  5. paulsz

    paulsz

    Joined:
    Mar 25, 2010
    Posts:
    29
    Sounds interresting and it's probably a good idea. Can you tell me exactly how to ping the master server ? Is it like polling it for hosts ?
    Thx
     
  6. iceshaft07

    iceshaft07

    Joined:
    Jul 23, 2010
    Posts:
    293
    Hey-- I'm actually working on some networking things myself.

    For the time being, I am using code like this:
    Code (csharp):
    1.  
    2.         //excerpt from code
    3.     lastIsConnectedToInternet = isConnectedToInternet;
    4.     isConnectedToInternet = false;
    5.    
    6. #if UNITY_EDITOR
    7.     if (Network.player.ipAddress.ToString() != "127.0.0.1")
    8.     {
    9.         isConnectedToInternet = true;      
    10.     }
    11. #endif
    12. #if UNITY_IPHONE
    13.     if (iPhoneSettings.internetReachability == iPhoneNetworkReachability.ReachableViaWiFiNetwork)
    14.     {
    15.         isConnectedToInternet = true;
    16.     }
    17. #endif
    18. #if UNITY_ANDROID
    19.     if (iPhoneSettings.internetReachability == iPhoneNetworkReachability.ReachableViaWiFiNetwork)
    20.     {
    21.         isConnectedToInternet = true;
    22.     }
    23. #endif
    24. #if (!UNITY_IPHONE  !UNITY_ANDROID)
    25.     if (Network.player.ipAddress.ToString() != "127.0.0.1")
    26.     {
    27.         isConnectedToInternet = true;
    28.  
    29.     }
    30. #endif
    31.  
    32.     if (lastIsConnectedToInternet != isConnectedToInternet)
    33.     {
    34.         wasNotifiedNetwork = false;
    35.     }
    36.  
    This works pretty decent in web player-- I can receive notifications when the network changes, and I just set the screen resolution to that of an iPhone, so it is a pretty good simulation.

    I'm about to try the above code out on the iPhone to see what happens. I can confirm that the above code does NOT work for the android, since for some reason the IP address ALWAYS returns 127.0.0.1, even if you ARE connected to a network.

    I'll let you know in a few.
     
  7. gecko938

    gecko938

    Joined:
    Dec 28, 2011
    Posts:
    12
    For anyone considering using the Ping technique, I just want to point out that the C# Ping class is not available in web player builds due to security sandboxing. See: http://unity3d.com/support/documentation/ScriptReference/MonoCompatibility.html

    I didn't realize this at first and spent a bit of time wondering why the compiler was complaining about not finding the System.Net.NetworkInformation namespace.
     
  8. dexl

    dexl

    Joined:
    Apr 21, 2011
    Posts:
    13
  9. Neogene

    Neogene

    Joined:
    Dec 29, 2010
    Posts:
    95
  10. blindgoat

    blindgoat

    Joined:
    Oct 24, 2012
    Posts:
    31
    Neo - What are we supposed to use then? All the other Networking functionality for reachability seems to be deprecated and Application.internetReachability seems to be the only option now.
     
    Last edited: Jul 31, 2013
  11. Jamora

    Jamora

    Joined:
    Mar 5, 2013
    Posts:
    9
    Application.internetReachability actually only checks if there is a networking capability. It returns a member of an enum NetworkReachability, that is, either no connection, a data packet connection, or a wifi/ethernet connection possibility . It doesn't check if the device is connected to a network with the device.

    It could be named better.
     
  12. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    439
    To truly know you're online, you need to implement "captive portal detection", to know if you're e.g. hitting a public WiFi login page. So just checking Application.internetReachability or doing a Ping to some address doesn't guarantee you can successfully make connections or make WWW requests.

    I have made an easy asset called Internet Reachability Verifier. It keeps you up-to-date whether you have verified internet access (WWW requests can be done).
    More info here: http://j.mp/IRVUN
     
  13. AndreasC

    AndreasC

    Joined:
    Feb 12, 2013
    Posts:
    31
    Please stop advertising your own products...
     
  14. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    826
    Just in case somebody finds the thread like I did, the above answers are quite old, I think a legit solution is to ping the masterserver asynchronous, my solution looks like this:

    Code (CSharp):
    1. private IEnumerator CheckConnectionToMasterServer() {
    2.         Ping pingMasterServer = new Ping("67.225.180.24");
    3.         Debug.Log(pingMasterServer.ip);
    4.         float startTime = Time.time;
    5.         while (!pingMasterServer.isDone && Time.time < startTime + 5.0f) {
    6.             yield return new WaitForSeconds(0.1f);
    7.         }
    8.         if(pingMasterServer.isDone && pingMasterServer.time >= 0) {
    9.             new InternetConnectionMessage();
    10.         } else {
    11.             new NoInternetConnectionMessage();
    12.         }
    13.     }
    It tries to ping the masterserver for 5 seconds or until it gets a response and afterwards sends a message whether there is a connection. (Should work for all platforms)
    Oh and you call the method like that:
    Code (CSharp):
    1. StartCoroutine(CheckConnectionToMasterServer());
     
    Last edited: Jun 8, 2021
    Timmy-Hsu, shaneK001, arjunh and 2 others like this.
  15. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    439
    @Johannski thanks for posting example code. But, for better reliability, it's probably best to combine your way with the "captive portal detection", because those public-wifi-login-systems may still let a simple Ping get through even if they block actual access.
     
  16. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    826
    @tonic Hm, you have a point there. I didn't try it, but there are probably systems out there, which let pings trough, but nothing else. I think for most purposes my code will be enough to check if there is a connection, but it won't handle all border cases.
     
  17. Christop

    Christop

    Joined:
    Aug 21, 2012
    Posts:
    60
    Hi
    i am also try to find a simple way of testing network connectivity.
    what do the new InternetConnectionMessage();/new NoInternetConnectionMessage(); do?
    In general how is a good way to get feedback results from an asychronous function?

    Thanks
     
  18. jrobertomar

    jrobertomar

    Joined:
    May 29, 2014
    Posts:
    1
    Hi @Johannski
    Just one question, the IP you're using... where is it from? Is it from a server of yours? Or is it something like Google? So that I know that I can rely on that one IP. Thanks!
     
  19. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    826
    Hi @jrobertomar, this address is from a server of mine, because the servers were also needed to play the game and so I could check two things at once. If you just want to know if you got Internet, I recommend to use 8.8.8.8. It is the address of Google, so it will be pingable unless the world ends or you have no Internet connection ;)
     
    jrobertomar likes this.
  20. zero_null

    zero_null

    Joined:
    Mar 11, 2014
    Posts:
    159
    any fixes yet ?
    or still need these workarounds?
     
  21. haroonkhan38

    haroonkhan38

    Joined:
    Oct 13, 2013
    Posts:
    2
    hi all,

    I am working on the same thing, I have to check two servers by ping. so calling web services from one of those live server.

    my ping works fine in unity editor and it inyellugently switch between available server

    issues comes on android build, the ping.time always returns -1 for both servers. even frim available server.

    any help appreciated in advance.