Internet Reachability Verifier - Support Thread

Internet Reachability Verifier for Unity.

LINK TO ASSET WEBSITE: Internet Reachability Verifier website.

So what does it do? After all, there’s already Application.internetReachability in the Unity API.

Application.internetReachability has a bit misleading name - it actually tells if it is technically possible for you to try to use the network. So, on a desktop machine it will always tell you that you can. On a mobile device it’s nice for checking if you’re really offline, or if you can try to make a connection (and if it is going to use WiFi or carrier data).

However, when using public WiFi, quite often you need to go through a login web page before the internet truly works. In such wireless network, any WWW request will actually give you the login page instead of the data you actually wanted. This is the situation where you want to use Internet Reachability Verifier.

What features does Internet Reachability Verifier have?

Accompanying pdf manual contains more details of each feature listed below.

  • Automatically monitors and verifies internet reachability, implemented using a light-weight coroutine.

  • If internet connectivity stops working middle of your own networking and you get error codes from some networking library, you can ask for reverification of the internet reachability (this asset will not actively monitor loss of effective networking, as that would use up user’s mobile data quota unnecessarily).

  • 16 different captive portal detection methods: Google204, Google204HTTPS, GoogleBlank, MicrosoftNCSI, MicrosoftNCSI_IPV6, Apple, Apple2, AppleHTTPS, Ubuntu, UbuntuHTTPS, MicrosoftConnectTest, MicrosoftConnectTest_IPV6, Custom.

  • Default setting is to automatically pick a suitable (“native”) captive portal detection method by platform.

  • Optional delegate for matching returned data for using custom method.

  • Optionally append cache buster to url when using the custom method.

  • Detailed internet access status property (Offline, PendingVerification, Error, Mismatch, NetVerified).

  • Easy callback for listening to changes in the internet access status property (optional).

About the implementation

  • Works with Desktop, Mobile and WebGL platforms
  • No native code.
  • C# source code included.
  • Small footprint. No nonsense of 100+ files. Whole asset package contains only a few files, and the actual needed code for your project is in a single MonoBehaviour (.cs file).
  • Supports Unity 6+, 2023, 2022, 2021, 2020, 2019, 2018, 2017
  • This is the original asset for this functionality. It’s maintained & most up-to-date.
  • Works with iOS app transport security and Android 9.0+ network security config.

Internet Reachability Verifier website

Other assets from Strobotnik: Google Universal Analytics for Unity, Dynamic Text, Klattersynth TTS

1 Like

v1.0.0 is now available!

@tonic : looks quite useful (though I would appreciate an actual support e-mail address…), anyway I was wondering in terms of compatibility, is there anything that would break this plug-in? Such as iOS updates or Unity updates in the foreseeable future? Just wondering because I’m trying to figure out if I should go with your option to fix an issue I have, or try to talk to prime31 about their Game Center plugin and see if they can resolve it (if you care what that is see below), any feedback is appreciated.

My specific issue: apparently a user can log into Game Center, then lose their internet connection but remain logged into Game Center. My app can upload saved score data while the user is offline and then submit it later, but just checking to see if they are logged into Game Center can yield a situation where the user is allowed to upload their scores while offline, think the upload succeeded, then look at the Game Center scoreboards (and of course their new scores won’t be there). So I’m looking for a way to remedy this possible issue, and your plug-in looked like a winner.

Hi @boddole . Short answer to your question about if the plug-in can be broken in the future: “it’s very unlikely, but possible”.

Better explanation with some details which may or may not make sense: This technique is based simply on using the Unity’s own WWW class, simple Unity updates shouldn’t make a big difference. However, e.g. the “Google204” captive portal detection requires check of the http status code, which is possible to get only in certain platforms with Unity’s own WWW class, and in differing ways (e.g. different response header key on android than on desktop). If they change this, then it may slightly affect how the verification works, but even in that case it should gracefully do a fallback to work w/o the header. Also, it’s of course possible that one of the big companies hosting the internet check stop keeping up their servers, although that’s highly unlikely as well. :slight_smile: Any way, you can opt to run own custom server for the file check.

Regarding your Game Center issue… to me that sounds like it would be more about prime31 needing to fix their plug-in, although you might be able to solve your issue by doing some own custom stuff with this asset… In your particular case though, it might be enough for you to just see that if (1) user already logged in game center successfully (there must be a valid connection), and (2) Unity’s own Application.internetReachability field suddenly equals NotReachable, then you know the submission is not going through… that is, you might be able to fix that without even buying my asset. (However, that kind of check wouldn’t work on e.g. desktop builds as they never report NotReachable, but obviously you’re not running on desktop).

v1.0.1 has been submitted for Asset Store reviewing – this version adds “Apple2” method (which mimics how iOS7 does the detection), and also explains in the manual why using custom method is recommended.

@tonic : Thank you for the detailed answer, I really appreciate it.

As you mentioned, using Unity’s Application.internetReachability would work for checking if the user has no connection, but (I think) that would still leave a gap where the users connection is available but they have not logged in to say a public wifi hotspot, which could prevent the sending of data to Game Center (again, not sure on that, maybe the data will make its way there anyway?). That is why I was so interested, because your plug-in could detect if the user was “truly” connected, and not just “had the potential to use the internet”.

BTW- prime31 got back to me, and apparently as long as the scores are packaged and sent correctly, Apple considers this a successful score submission, regardless of internet connectivity / Game Center verification (I love the way Apple thinks…).

@boddole , yes, my idea was under assumption that successful Game Center initialization/login would implicitly mean that there was proper internet connectivity, but that the user lost it. Perhaps that isn’t so, in which case my asset could indeed be useful to you.

Note that some captive portal systems used to run public WiFis actually have hardcoded checks for the captive portal checks, in which case even my asset can be fooled when using one of the standard options (I just noticed this happening with one airport wifi). For such cases the “custom” method should work more reliably but needs one to host own server or own file on some server for the checks, meaning a bit of extra hassle.

@tonic : I see, thank you again for the clarification.

Version 1.0.1 is now available!

Hi,
Do you have functionality to test if there has been no connection for a certain time period?
Use case would be checking internet reachability for android google lvl check.
In case user is offline they get a grace period before action is taken.
eg: along the lines of this thread LVL check - Unity Engine - Unity Discussions

ty!

Hi @sonicviz , there’s no ready-made function to return that info right now - maybe I’ll add that to next version. It is pretty easy to add though. Here’s a quick example how to do that by modifying SkeletonIRVExample.cs:

add these rows of new code:

    InternetReachabilityVerifier.Status prevStatus = InternetReachabilityVerifier.Status.Offline;
    float noInternetStartTime = 0;

    float getTimeWithoutInternetConnection()
    {
        if (prevStatus == InternetReachabilityVerifier.Status.NetVerified)
            return 0; // we're online
        else
            return Time.time - noInternetStartTime; // time without internet in seconds
    }

modify the implementation of netStatusChanged-method to this:

    void netStatusChanged(InternetReachabilityVerifier.Status newStatus)
    {
        Debug.Log("InternetReachabilityVerifier.Status: " + newStatus);
        if (prevStatus == InternetReachabilityVerifier.Status.NetVerified &&
            newStatus != InternetReachabilityVerifier.Status.NetVerified)
            noInternetStartTime = Time.time;
        prevStatus = newStatus;
    }

Now you can call getTimeWithoutInternetConnection() and it should always return 0 when user is online, and amount of seconds spent being offline if there’s no verified internet connectivity.

Thanks for the tips

Hey @tonic ,

we tried your IRV to check the internet connection for mobile devices and webplayer.

when i deactivate the wifi/wlan/lan component on the device - i only receive the error status from your script, not the offline status. Is this right?

So is there any possibility to distinguish between real errors and only no active internet connection? I want to display 2 different messages for the user: Error to contact the admin, and Offline to check InternetConnection

The first way i found to solve this problem is to analyse the lastError - String and search for keywords, like offline, resolve host, DNS, … . Do you know where i can find a list with all error messages, which the www class can throw? Or is there any other options for me?

thx :slight_smile:

Hi @quaigon ! This is going to be a bit long reply, as I think there’s no clear solution for you, but I’ll do my best to help anyway. Although I didn’t exactly get what kind of situation is the “error to contact admin” - is your app meant for some internal and not public use?

About WiFi and Offline: If you deactivate WiFi on the device, it may still be able to try connection using carrier data network like 3G if it’s available, in which case it doesn’t go into “Offline” status. The Offline status is reported only when there’s no chance to try connection (in this case also Unity’s Application.internetReachability equals NetworkReachability.NotReachable). On desktop computers that Offline state is basically never reported as they always tend to have LAN enabled even if there’s no internet connectivity. But on mobile devices you’ll get the Offline state if you enable airplane mode and make sure WiFi is not enabled.

For the Error status there’s unfortunately no easy way to distinguish between different possibilities what could be causing the error. This is because the error string is set by Unity’s WWW class implementation, which is implemented slightly differently for each platform (being a wrapper for a native class). Unfortunately this also means that the error strings are different on each platform and can differ even by the OS version.
For example, on Android non-existent url can result in “java.io.FileNotFoundException: http://wrong_url_here”. On iOS the same error in this case would be “404: not found”. And when running directly from Unity Editor on desktop Windows, it is “404: Not Found” (note different capitalization).

So, there’s no clear answer how to use the error string easily. If you still want to pursue that path further, below is some more info I found for both iOS and Android, which may be helpful to you.

iOS:
You can view the Unity’s WWW wrapper code by locating it in the Unity installation directory: Unity/Editor/Data/PlaybackEngines/iossupport/Trampoline/Classes/Unity/WWWConnection.mm.
There are two places which can send errors there - implementations of “didFailWithError:” and “didReceiveResponse:” (the latter one seems to used when http status code is e.g. in the 400 range). Both call native code to fetch error string (localizedDescription / localizedStringForStatusCode). For me that seemed to return strings in English even if I had set device to a different language.
Here’s instructions how you can get a list of English URL strings for iOS:
On your Mac, open a new Terminal. Then make a copy(!) of URL.strings file in Foundation framework:
cp /System/Library/Frameworks/Foundation.framework/Resources/en.lproj/URL.strings ~/tmp-URL.strings
Then run this command to convert the temp file to different format:
plutil -convert xml1 ~/tmp-URL.strings
Now you can view the tmp-URL.strings file as xml data, and see different types of response strings.

Android:
I am not sure, but I’m guessing that the used HttpURLConnection implementation might be the code that’s in following URL.
https://android.googlesource.com/platform/libcore/+/e810d3b49631329b11440aa5b7a54db181d42ed1/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java
I think you want to check at least implementations of getInputStream() starting at line 1134, and doRequestInternal() starting at line 1614. It doesn’t seem very clear what are the different types of responses.

I think most helpful might be to check the http status code, which is reported differently (if at all). For that, peek how CaptivePortalDetectionMethod.Google204 in checkCaptivePortalDetectionResult is implemented (InternetReachabilityVerifier.cs) - on desktop the response header string key is “STATUS”, on android it is funnily “NULL” (but it works). On iOS the status isn’t reported, but as you can see from my example 404 string, the start of WWW error string has the code. (On WinStore/WP8 builds the status is also missing, but right now I don’t have example error strings at hand to check if the status code is shown there.)

Again, note that the WWW class implementation has varied between Unity versions (especially between 3.x/4.0/4.x). And there are also differences based on OS version, so the above hints apply only to recent versions.

Hi @tonic , I’m developing a mobile app (iOS and Android) that must detect a local WiFi connection (based on a custom hardware configuration used for an automated gates system - the WiFi chip used is http://www.microchip.com/wwwproducts/Devices.aspx?product=RN171).
Then the app should send and receive string commands to communicate with the software developed in the gate hardware motherboard.

I would like to know if your library can solve these problems:

  • detect the WiFi connection available
  • establish the connection
  • communicate with the local server

I need your reply as soon as possible due to the project deadline.
Thank you in advance

Hi @NeedNap_1 . Since you have a somewhat custom situation regarding the WiFi connection, I’m not sure if it is possible to use this package in your case or not.

But, if the WiFi chip&connection works like any other network/WiFi connection would in Unity’s view, then it should be possible to use this package using the “Custom” detection method.

For the Custom method, you need to place a file to your local server, and the InternetReachabilityVerifier (IRV) component should then be configured to use the local url to that file. The file must have known contents (maybe just “OK” or “wifi available” - this same thing will be set for the IRV component). Additionally you should make sure the local server is configured so that it doesn’t set cache control info for the file (so that client can assume it always needs to be fetched again when asking for it).

After that, rest of communication with the local server is of course up to you, after you know from this package that the connection should be functional. :slight_smile:

Thank you @tonic , I’ll try it as soon as possible and I’ll let you know the result.

demo apk??

@imtrobin there’s no separate demo version available, if that’s what you’re asking.

currently, I am using your plugin to successfully determine if the internet is available and it works well.

However, I need to know if the internet is wifi or cellular as cellular gives me problems.

I found this link https://github.com/xamarin/monotouch-samples/blob/master/ReachabilitySample/reachability.cs

which has an enum

public enum NetworkStatus
{
NotReachable,
ReachableViaCarrierDataNetwork,
ReachableViaWiFiNetwork
}

would you consider adding this additional information to your plugin?