Facepunch / Facepunch.Steamworks

Another fucking c# Steamworks implementation
MIT License
2.92k stars 350 forks source link

End-to-end connection: closed due to problem detected locally, reason code 5003. (Timed out attempting to connect) #268

Closed laurirasanen closed 5 years ago

laurirasanen commented 5 years ago

Basic listen server using SteamNetworkingSockets results in connection error in 2.0 alpha 2 release. Windows firewall and AV disabled.
Attempts to connect for ~10 seconds and then spews out the following in ConnectionInterface.Connection.DetailedStatus():

End-to-end connection: closed due to problem detected locally, reason code 5003.  (Timed out attempting to connect)
    Current rates:
        Sent:   0.0 pkts/sec   0.0 K/sec
        Recv:   0.0 pkts/sec   0.0 K/sec
        Ping:0ms    Max latency variance: ???ms
        Est avail bandwidth: 128.0KB/s  
        Bytes buffered: 0
    Lifetime stats:
        Totals
            Sent:         23 pkts          11,065 bytes
            Recv:          3 pkts             544 bytes
        No ping distribution available.  (1 samples)
        No connection quality distribution available.  (0 measurement intervals)
        Latency variance histogram not available
        TX Speed histogram: (9 total samples)
             0 - 16 KB/s:    9  100%
            16 - 32 KB/s:    0    0%
            32 - 64 KB/s:    0    0%
           64 - 128 KB/s:    0    0%
          128 - 256 KB/s:    0    0%
          256 - 512 KB/s:    0    0%
         512 - 1024 KB/s:    0    0%
              1024+ KB/s:    0    0%
        Transmit speed distribution:
            50% of speeds <=    0 KB/s
            75% of speeds <=    0 KB/s
        RX Speed histogram: (9 total samples)
             0 - 16 KB/s:    9  100%
            16 - 32 KB/s:    0    0%
            32 - 64 KB/s:    0    0%
           64 - 128 KB/s:    0    0%
          128 - 256 KB/s:    0    0%
          256 - 512 KB/s:    0    0%
         512 - 1024 KB/s:    0    0%
              1024+ KB/s:    0    0%
        Receive speed distribution:
            50% of speeds <=    0 KB/s
            75% of speeds <=    0 KB/s
    No rate stats received from remote host
    No lifetime stats received from remote host

Code:

using UnityEngine;
using Steamworks;
using Steamworks.Data;
using System.Threading.Tasks;

public class NetworkTest : MonoBehaviour
{
    SocketInterface socket = null;
    ConnectionInterface connection = null;

    public void Awake()
    {
        StartServer();
        StartClient();
    }

    public void Update()
    {
        connection?.Receive();
        socket?.Receive();
        SteamServer.RunCallbacks();
        SteamClient.RunCallbacks();
    }

    public void StartServer()
    {
        SteamServerInit serverInit = new SteamServerInit( "SteamNetworkingSockets", "SteamNetworkingSockets test" )
        {
            GamePort = 28015,
            Secure = true,
            QueryPort = 28016,
            VersionString = Application.version
        };

        try
        {
            SteamServer.Init( 480, serverInit );
            SteamServer.LogOnAnonymous();

            socket = SteamNetworkingSockets.CreateNormalSocket<SocketInterface>( NetAddress.AnyIp( 28015 ) );
        }
        catch (System.Exception e)
        {
            // Couldn't init for some reason (dll errors, blocked ports)
            Debug.LogException( e, this );
        }
    }

    public async void StartClient()
    {
        // Wait for server to start
        await Task.Delay( 1000 );

        try
        {
            SteamClient.Init( 480 );

            connection = SteamNetworkingSockets.ConnectNormal<ConnectionInterface>( NetAddress.From( "127.0.0.1", 28015 ) );
            ConnectionStatusAsync();
        }
        catch (System.Exception e)
        {
            // Couldn't init for some reason (steam is closed etc)
            Debug.LogException( e );
        }
    }

    async void ConnectionStatusAsync()
    {
        while(connection != null && !connection.Connected)
        {
            Debug.Log( connection.Connection.DetailedStatus() );
            await Task.Delay( 1000 );
        }
    }

    public void OnDisable()
    {
        connection?.Close();
        connection = null;
        socket?.Close();
        SteamClient.Shutdown();
        SteamServer.Shutdown();
    }
}

Ifdef'ing SERVER and CLIENT separately and running the server in batch mode gives some extra info:

\src\steamnetworkingsockets\clientlib\steamnetworkingsockets_connections.cpp (1816) : Assertion Failed: Application didn't accept or close incoming connection in a reasonable amount of time.  This is probably a bug.
\src\steamnetworkingsockets\clientlib\steamnetworkingsockets_lowlevel.cpp (117) : Assertion Failed: SteamDatagramTransportLock held for 187.8ms!
laurirasanen commented 5 years ago

Looks like SteamClient.Init needs to be called before calling SteamNetworkingSockets.CreateNormalSocket, works as expected after this.

Caused by SteamNetworkingSockets.InstallEvents only being called in SteamClient.Init and not in SteamServer.Init. Also the server bool parameter in SteamNetConnectionStatusChangedCallback_t.Install is always set to false.

Created pull request #269 to make use of the boolean and call SteamNetworkingSockets.InstallEvents in SteamServer.Init as well.