Ejemplo n.º 1
0
    /// <remarks>
    /// Affected by frame-rate of app, as this Coroutine checks the socket for a result once per frame.
    /// </remarks>
    public IEnumerator PingSocket(Region region)
    {
        region.Ping = Attempts * MaxMilliseconsPerPing;

        this.PingsRunning++;
        PhotonPing ping;

        if (PhotonHandler.PingImplementation == typeof(PingNativeDynamic))
        {
            Debug.Log("Using constructor for new PingNativeDynamic()"); // it seems on android, the Activator can't find the default Constructor
            ping = new PingNativeDynamic();
        }
        else if (PhotonHandler.PingImplementation == typeof(PingMono))
        {
            ping = new PingMono(); // using this type explicitly saves it from IL2CPP bytecode stripping
        }
        #if UNITY_WEBGL
        else if (PhotonHandler.PingImplementation == typeof(PingHttp))
        {
            ping = new PingHttp();
        }
        #endif
        else
        {
            ping = (PhotonPing)Activator.CreateInstance(PhotonHandler.PingImplementation);
        }

        //Debug.Log(region);

        float rttSum     = 0.0f;
        int   replyCount = 0;

        // all addresses for Photon region servers will contain a :port ending. this needs to be removed first.
        // PhotonPing.StartPing() requires a plain (IP) address without port or protocol-prefix (on all but Windows 8.1 and WebGL platforms).

        string regionAddress = region.HostAndPort;
        int    indexOfColon  = regionAddress.LastIndexOf(':');
        if (indexOfColon > 1)
        {
            regionAddress = regionAddress.Substring(0, indexOfColon);
        }

        regionAddress = ResolveHost(regionAddress);

        for (int i = 0; i < Attempts; i++)
        {
            bool      overtime = false;
            Stopwatch sw       = new Stopwatch();
            sw.Start();

            try
            {
                ping.StartPing(regionAddress);
            }
            catch (Exception e)
            {
                Debug.Log("catched: " + e);
                this.PingsRunning--;
                break;
            }


            while (!ping.Done())
            {
                if (sw.ElapsedMilliseconds >= MaxMilliseconsPerPing)
                {
                    overtime = true;
                    break;
                }
                yield return(0); // keep this loop tight, to avoid adding local lag to rtt.
            }
            int rtt = (int)sw.ElapsedMilliseconds;


            if (IgnoreInitialAttempt && i == 0)
            {
                // do nothing.
            }
            else if (ping.Successful && !overtime)
            {
                rttSum += rtt;
                replyCount++;
                region.Ping = (int)((rttSum) / replyCount);
                //Debug.Log("region " + region.Code + " RTT " + region.Ping + " success: " + ping.Successful + " over: " + overtime);
            }

            yield return(new WaitForSeconds(0.1f));
        }

        this.PingsRunning--;

        //Debug.Log("this.PingsRunning: " + this.PingsRunning + " this debug: " + ping.DebugString);
        yield return(null);
    }
    /// <remarks>
    /// Affected by frame-rate of app, as this Coroutine checks the socket for a result once per frame.
    /// </remarks>
    public IEnumerator PingSocket(Region region)
    {
        region.Ping = Attempts * MaxMilliseconsPerPing;

        this.PingsRunning++; // TODO: Add try-catch to make sure the PingsRunning are reduced at the end and that the lib does not crash the app
        PhotonPing ping = null;

        #if NATIVE_SOCKETS && NATIVE_SOCKETS_STATIC
        if (PhotonHandler.PingImplementation == typeof(PingNativeStatic))
        {
            Debug.Log("Using constructor for new PingNativeStatic()"); // it seems on Switch, the Activator can't find the default Constructor
            ping = new PingNativeStatic();
        }
        #elif NATIVE_SOCKETS
        if (PhotonHandler.PingImplementation == typeof(PingNativeDynamic))
        {
            Debug.Log("Using constructor for new PingNativeDynamic()"); // it seems on Android, the Activator can't find the default Constructor
            ping = new PingNativeDynamic();
        }
        #elif UNITY_WEBGL
        if (PhotonHandler.PingImplementation == typeof(PingHttp))
        {
            ping = new PingHttp();
        }
        #elif NETFX_CORE
        ping = new PingWindowsStore();
        #else
        if (PhotonHandler.PingImplementation == typeof(PingMono))
        {
            ping = new PingMono(); // using this type explicitly saves it from IL2CPP bytecode stripping
        }
        #endif

        if (ping == null)
        {
            ping = (PhotonPing)Activator.CreateInstance(PhotonHandler.PingImplementation);
        }

        //Debug.Log(region);

        float rttSum     = 0.0f;
        int   replyCount = 0;

        // all addresses for Photon region servers will contain a :port ending. this needs to be removed first.
        // PhotonPing.StartPing() requires a plain (IP) address without port or protocol-prefix (on all but Windows 8.1 and WebGL platforms).

        string regionAddress = region.HostAndPort;
        int    indexOfColon  = regionAddress.LastIndexOf(':');
        if (indexOfColon > 1)
        {
            regionAddress = regionAddress.Substring(0, indexOfColon);
        }

        // we also need to remove the protocol or Dns.GetHostAddresses(hostName) will throw an exception
        // This is for xBox One for example.
        int indexOfProtocol = regionAddress.IndexOf(PhotonPingManager.wssProtocolString);
        if (indexOfProtocol > -1)
        {
            regionAddress = regionAddress.Substring(indexOfProtocol + PhotonPingManager.wssProtocolString.Length);
        }
        regionAddress = ResolveHost(regionAddress);

        //Debug.Log("Ping Debug - PhotonHandler.PingImplementation: " + PhotonHandler.PingImplementation + " ping.GetType():" + ping.GetType() + " regionAddress:" + regionAddress);
        for (int i = 0; i < Attempts; i++)
        {
            bool      overtime = false;
            Stopwatch sw       = new Stopwatch();
            sw.Start();

            try
            {
                ping.StartPing(regionAddress);
            }
            catch (Exception e)
            {
                Debug.Log("catched: " + e);
                this.PingsRunning--;
                break;
            }


            while (!ping.Done())
            {
                if (sw.ElapsedMilliseconds >= MaxMilliseconsPerPing)
                {
                    overtime = true;
                    break;
                }
                yield return(0); // keep this loop tight, to avoid adding local lag to rtt.
            }
            int rtt = (int)sw.ElapsedMilliseconds;


            if (IgnoreInitialAttempt && i == 0)
            {
                // do nothing.
            }
            else if (ping.Successful && !overtime)
            {
                rttSum += rtt;
                replyCount++;
                region.Ping = (int)((rttSum) / replyCount);
                //Debug.Log("region " + region.Code + " RTT " + region.Ping + " success: " + ping.Successful + " over: " + overtime);
            }

            yield return(new WaitForSeconds(0.1f));
        }
        ping.Dispose();

        this.PingsRunning--;

        //Debug.Log("this.PingsRunning: " + this.PingsRunning + " this debug: " + ping.DebugString);
        yield return(null);
    }