12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- using UnityEngine;
- using System.Collections;
- using System.Net;
- using System.Net.Sockets;
- /// <summary>
- /// 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.
- /// </summary>
- 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;
- }
- }
- }
|