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.
Unity check internet connection availability
Asked Answered
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
- 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.
- 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.
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 Ping
–
Boatyard 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.1 –
Phelan
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";
}
}
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;
}
}
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. #76224272 –
Enneagon
© 2022 - 2024 — McMap. All rights reserved.