Unity check internet connection availability
Asked Answered
A

3

8

I am porting our game to Unity, and need some help regarding internet connectivity check in Unity. Official Unity Documentation says 'do not use Application.internetReachability. So i am confused which code will work here. Didn't find any prominent solution in any forum. I want to check whether wi-fi or GPRS is on or not which should work for iOS and Android. Thanks in advance.

Ability answered 22/6, 2014 at 12:20 Comment(0)
B
24

Solution

Application.internetReachability is what you need. In conjunction with Ping, probably.

Here's an example:

using UnityEngine;

public class InternetChecker : MonoBehaviour
{
    private const bool allowCarrierDataNetwork = false;
    private const string pingAddress = "8.8.8.8"; // Google Public DNS server
    private const float waitingTime = 2.0f;

    private Ping ping;
    private float pingStartTime;

    public void Start()
    {
        bool internetPossiblyAvailable;
        switch (Application.internetReachability)
        {
            case NetworkReachability.ReachableViaLocalAreaNetwork:
                internetPossiblyAvailable = true;
                break;
            case NetworkReachability.ReachableViaCarrierDataNetwork:
                internetPossiblyAvailable = allowCarrierDataNetwork;
                break;
            default:
                internetPossiblyAvailable = false;
                break;
        }
        if (!internetPossiblyAvailable)
        {
            InternetIsNotAvailable();
            return;
        }
        ping = new Ping(pingAddress);
        pingStartTime = Time.time;
    }

    public void Update()
    {
        if (ping != null)
        {
            bool stopCheck = true;
            if (ping.isDone)
            {
                if (ping.time >= 0)
                    InternetAvailable();
                else
                    InternetIsNotAvailable();
            }
            else if (Time.time - pingStartTime < waitingTime)
                stopCheck = false;
            else
                InternetIsNotAvailable();
            if (stopCheck)
                ping = null;
        }
    }

    private void InternetIsNotAvailable()
    {
        Debug.Log("No Internet :(");
    }

    private void InternetAvailable()
    {
        Debug.Log("Internet is available! ;)");
    }
}

Things to note

  1. Unity's ping doesn't do any domain name resolutions, i.e. it only accepts IP addresses. So, if some player has Internet access but has some DNS problems, the method will say that he has Internet.
  2. It's only a ping check. Don't expect it to be 100% accurate. In some rare cases it will provide you with false information.
Boatyard answered 22/6, 2014 at 13:28 Comment(13)
Checked that already. Read their official note on that link which says "Note: Do not use this property to determine the actual connectivity."Ability
This is why I wrote In conjunction with PingBoatyard
Sorry but can you please provide any link or sample code? i tried forum.unity3d.com/threads/… this link but didn't work.Ability
Cool, that worked great in editor! Will check for iOS and Android now.Ability
Yeah it did, just i made few changes for my convenience.Ability
ping.isDone is true where where's no internet connection on Android !!Occurrence
Hm... And what is the value of ping.time in this case?Boatyard
You need a Captive Portal Detection polling watchdog as mentioned above by tonic.Jacintojack
In the code above, when ping.isDone is true, it should really verify ping.time is not -1, indicating the host was unavailable.Liebowitz
@NathanHyde negative time is definitely a bad sign. But I would refrain from giving it a specific treatment since the documentation doesn't say anything about it. I've updated the answer though to handle such a case.Boatyard
@SergeyKrusch Very true about the docs. That's just been my experience. BTW, thanks for the code. It's a great foundation to build on.Liebowitz
@Liebowitz how can you confirm that?Larrainelarrie
new Ping("8.8.8.8") does not work in my Unity 2018.3.6f with target platform Windows even though I have internet. Only works for local IPs like 127.0.0.1Phelan
C
1

What I do is Network.TestConnection which tests for connectivity, whether or not it can be a server, and whether or not NAT punch through can be used successfully.

This is the sample code they have given us. If the result is ConnectionTesterStatus.Error, chances are there is no internet access.

var testStatus = "Testing network connection capabilities.";
var testMessage = "Test in progress";
var shouldEnableNatMessage : String = "";
var doneTesting = false;
var probingPublicIP = false;
var serverPort = 9999;
var connectionTestResult = ConnectionTesterStatus.Undetermined;

// Indicates if the useNat parameter be enabled when starting a server
var useNat = false;

function OnGUI() {
    GUILayout.Label("Current Status: " + testStatus);
    GUILayout.Label("Test result : " + testMessage);
    GUILayout.Label(shouldEnableNatMessage);
    if (!doneTesting)
        TestConnection();
}

function TestConnection() {
    // Start/Poll the connection test, report the results in a label and 
    // react to the results accordingly
    connectionTestResult = Network.TestConnection();
    switch (connectionTestResult) {
        case ConnectionTesterStatus.Error: 
            testMessage = "Problem determining NAT capabilities";
            doneTesting = true;
            break;

        case ConnectionTesterStatus.Undetermined: 
            testMessage = "Undetermined NAT capabilities";
            doneTesting = false;
            break;

        case ConnectionTesterStatus.PublicIPIsConnectable:
            testMessage = "Directly connectable public IP address.";
            useNat = false;
            doneTesting = true;
            break;

        // This case is a bit special as we now need to check if we can 
        // circumvent the blocking by using NAT punchthrough
        case ConnectionTesterStatus.PublicIPPortBlocked:
            testMessage = "Non-connectable public IP address (port " +
                serverPort +" blocked), running a server is impossible.";
            useNat = false;
            // If no NAT punchthrough test has been performed on this public 
            // IP, force a test
            if (!probingPublicIP) {
                connectionTestResult = Network.TestConnectionNAT();
                probingPublicIP = true;
                testStatus = "Testing if blocked public IP can be circumvented";
                timer = Time.time + 10;
            }
            // NAT punchthrough test was performed but we still get blocked
            else if (Time.time > timer) {
                probingPublicIP = false;        // reset
                useNat = true;
                doneTesting = true;
            }
            break;
        case ConnectionTesterStatus.PublicIPNoServerStarted:
            testMessage = "Public IP address but server not initialized, "+
                "it must be started to check server accessibility. Restart "+
                "connection test when ready.";
            break;

        case ConnectionTesterStatus.LimitedNATPunchthroughPortRestricted:
            testMessage = "Limited NAT punchthrough capabilities. Cannot "+
                "connect to all types of NAT servers. Running a server "+
                "is ill advised as not everyone can connect.";
            useNat = true;
            doneTesting = true;
            break;

        case ConnectionTesterStatus.LimitedNATPunchthroughSymmetric:
            testMessage = "Limited NAT punchthrough capabilities. Cannot "+
                "connect to all types of NAT servers. Running a server "+
                "is ill advised as not everyone can connect.";
            useNat = true;
            doneTesting = true;
            break;

        case ConnectionTesterStatus.NATpunchthroughAddressRestrictedCone:
        case ConnectionTesterStatus.NATpunchthroughFullCone:
            testMessage = "NAT punchthrough capable. Can connect to all "+
                "servers and receive connections from all clients. Enabling "+
                "NAT punchthrough functionality.";
            useNat = true;
            doneTesting = true;
            break;

        default: 
            testMessage = "Error in test routine, got " + connectionTestResult;
    }
    if (doneTesting) {
        if (useNat)
            shouldEnableNatMessage = "When starting a server the NAT "+
                "punchthrough feature should be enabled (useNat parameter)";
        else
            shouldEnableNatMessage = "NAT punchthrough not needed";
        testStatus = "Done testing";
    }
}
Chubby answered 10/6, 2015 at 21:29 Comment(0)
F
-3

This is a simple solution that I am already using for Internet check. It works for both IOS and Android. I know that it may need improvements, but here it is:

public static bool InternetStatus ()
{
    if (Application.internetReachability != NetworkReachability.NotReachable)
    {
        return true;
    }else{
        return false;
    }
}
Figge answered 25/7, 2015 at 6:30 Comment(2)
It is already mention in question that Unity docs does not recommend this solution.Mcclimans
If you use this, when your device connect to WIFI without internet connection, above function will return true. So it's not realiable. #76224272Enneagon

© 2022 - 2024 — McMap. All rights reserved.