using UnityEngine; using System.Collections; using System.Net; using System.Net.Sockets; /// /// This component is responsible for continously checking if there is an internet connection. /// This is done by first checking the Application.internetReachability. But this can give false /// positives, e.g. connected to a wifi router but does not have an actual internet connection. /// So the next step is pinging PING_DESTINATION every TIME_BETWEEN_PINGS seconds. /// If the ping fails for FAILED_PINGS_DISCONNECTION_TRIGGER times, it means it has gone offline. /// Whenever the connectivity changes, a ConnectivityChange notification is fired. /// public class ConnectivityPollManager : MonoBehaviour { static bool _hasInternet; public static bool HasInternet { get { return _hasInternet; } } private const string PING_DESTINATION = "https://game.gamatic.com/ping_do_not_delete.html"; const float TIME_BETWEEN_PINGS = 3; //seconds //sometimes the ping just fails every once in a while, so we should do multiple pings just to make sure const int FAILED_PINGS_DISCONNECTION_TRIGGER = 3; bool _hasPingedDestination; string _address; int _failedPings; void Start() { StartCoroutine(CheckForConnectivityCoroutine()); } IEnumerator CheckForConnectivityCoroutine() { while (true) { bool isNetworkReachable = (Application.internetReachability != NetworkReachability.NotReachable); //If the api says that it is reachable, we need to test further by pinging a proper connection if (isNetworkReachable) { yield return StartCoroutine(TestConnectionCoroutine()); if (_hasPingedDestination != _hasInternet) { if (!_hasPingedDestination) { ++_failedPings; if (_failedPings >= FAILED_PINGS_DISCONNECTION_TRIGGER) { AVDebug.Log("Went offline"); _hasInternet = false; CoreNotificationCenter.Post(CoreNotificationType.ConnectivityChange, _hasPingedDestination); } else { AVDebug.Log("Ping missed"); } } else { AVDebug.Log("Back online"); _hasInternet = true; _failedPings = 0; CoreNotificationCenter.Post(CoreNotificationType.ConnectivityChange, _hasPingedDestination); } } } else { //Network was not reachable if (_hasInternet) { AVDebug.Log("Went offline (airplane mode/wifi off?)"); _hasInternet = false; CoreNotificationCenter.Post(CoreNotificationType.ConnectivityChange, _hasPingedDestination); } } yield return new WaitForSeconds(TIME_BETWEEN_PINGS); } } //Inspired from http://forum.unity3d.com/threads/68938-How-can-you-tell-if-there-exists-a-network-connection-of-any-kind //Its result is stored in _hasPingedDestination, since coroutines cannot return a value directly IEnumerator TestConnectionCoroutine() { _hasPingedDestination = false; WWW www = new WWW(PING_DESTINATION); yield return www; if (www.error == null) { _hasPingedDestination = true; } } }