Search Unity

Question Problem with reconnecting in the unity transport

Discussion in 'Unity Transport' started by ElegantUniverse, Dec 26, 2021.

  1. ElegantUniverse

    ElegantUniverse

    Joined:
    Sep 13, 2018
    Posts:
    78
    hello
    Im using this code for reconnect the client to the server
    Code (CSharp):
    1.  
    2.     if (_serverEndPoint.IsValid && !_networkConnection.IsCreated)
    3.         {
    4.              _networkConnection = _clientDrive.Connect(_serverEndPoint);//handle background stuff
    5.             print("Re-connecting...");
    6.         }
    7.  
    the mentioned code works fine for the first time that the client wants to connect to the server . when I interrupt the internet for 30 s unity transport server disconnect the client when I try to reconnect the client to the server with this code :

    Code (CSharp):
    1.             if (!_serverEndPoint.IsValid)
    2.                 {
    3.                     _networkConnection = _clientDrive.Connect(_serverEndPoint);
    4.  
    5.                     print("Re-connecting...");
    6.                 }
    I face with this error and never connect again :



    Code (CSharp):
    1.  
    2. Cannot send data while connecting
    3. 0x00007ff73825596c (Unity) StackWalker::GetCurrentCallstack
    4. 0x00007ff73825dd49 (Unity) StackWalker::ShowCallstack
    5. 0x00007ff73976525c (Unity) GetStacktrace
    6. 0x00007ff73a88be43 (Unity) DebugStringToFile
    7. 0x00007ff7382be246 (Unity) DebugLogHandler_CUSTOM_Internal_Log
    8. 0x0000019e294b313b (Mono JIT Code) (wrapper managed-to-native) UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
    9. 0x0000019e294b2fdb (Mono JIT Code) UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
    10. 0x0000019e294b24fe (Mono JIT Code) UnityEngine.Logger:Log (UnityEngine.LogType,object)
    11. 0x0000019e298a72aa (Mono JIT Code) UnityEngine.Debug:LogError (object)
    12. 0x0000019e29851633 (Mono JIT Code) [NetworkDriver.cs:162] Unity.Networking.Transport.NetworkDriver/Concurrent:BeginSend (Unity.Networking.Transport.NetworkPipeline,Unity.Networking.Transport.NetworkConnection,Unity.Networking.Transport.DataStreamWriter&,int)
    13. 0x0000019e2984ff13 (Mono JIT Code) [NetworkDriver.cs:970] Unity.Networking.Transport.NetworkDriver:BeginSend (Unity.Networking.Transport.NetworkPipeline,Unity.Networking.Transport.NetworkConnection,Unity.Networking.Transport.DataStreamWriter&,int)
    14. 0x0000019e2984ed7b (Mono JIT Code) [ClientCode.cs:263] ClientCode:SendUnReliableDataToServer (byte[])
    15. 0x0000019e2984e84b (Mono JIT Code) [SendAllDataToServer.cs:133] SendAllDataToServer:SendUnreliablePositionToServer (int,single,single,single,single,single,single)
    16. 0x0000019e2983172b (Mono JIT Code) [SendAllDataToServer.cs:26] SendAllDataToServer:Update ()
    17. 0x0000019e2cebd968 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
    18. 0x00007ffd1be9e650 (mono-2.0-bdwgc) [mini-runtime.c:2812] mono_jit_runtime_invoke
    19. 0x00007ffd1be22ae2 (mono-2.0-bdwgc) [object.c:2921] do_runtime_invoke
    20. 0x00007ffd1be2bb3f (mono-2.0-bdwgc) [object.c:2968] mono_runtime_invoke
    21. 0x00007ff7380dd844 (Unity) scripting_method_invoke
    22. 0x00007ff7380d6195 (Unity) ScriptingInvocation::Invoke
    23. 0x00007ff738083614 (Unity) MonoBehaviour::CallMethodIfAvailable
    24. 0x00007ff73808371c (Unity) MonoBehaviour::CallUpdateMethod
    25. 0x00007ff73754ada8 (Unity) BaseBehaviourManager::CommonUpdate<BehaviourManager>
    26. 0x00007ff737554cfa (Unity) BehaviourManager::Update
    27. 0x00007ff7379bd66a (Unity) `InitPlayerLoopCallbacks'::`2'::UpdateScriptRunBehaviourUpdateRegistrator::Forward
    28. 0x00007ff73799e1bc (Unity) ExecutePlayerLoop
    29. 0x00007ff73799e293 (Unity) ExecutePlayerLoop
    30. 0x00007ff7379a50c9 (Unity) PlayerLoop
    31. 0x00007ff738dee2b1 (Unity) PlayerLoopController::UpdateScene
    32. 0x00007ff738debf46 (Unity) Application::TickTimer
    33. 0x00007ff73976ea51 (Unity) MainMessageLoop
    34. 0x00007ff739772a91 (Unity) WinMain
    35. 0x00007ff73b5ba396 (Unity) __scrt_common_main_seh
    36. 0x00007ffd6f1b7034 (KERNEL32) BaseThreadInitThunk
    37. 0x00007ffd71102651 (ntdll) RtlUserThreadStart
    38.  
     
    Last edited: Dec 26, 2021
  2. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    If you want to check if a connection is alive, you should use the
    NetworkDriver.GetConnectionState
    method. Checking
    IsValid
    on a network endpoint will only tell you if that endpoint is well-formatted (basically if the IP address is valid).
     
    ElegantUniverse likes this.
  3. ElegantUniverse

    ElegantUniverse

    Joined:
    Sep 13, 2018
    Posts:
    78
    hi @simon-lemay-unity
    I used what you recommended, this is my code

    Code (CSharp):
    1.      
    2.         if (_clientDrive.GetConnectionState(_networkconnection) == NetworkConnection.State.Disconnected)
    3.         {
    4.            print("client is disconnected.....");
    5.             _clientDisConnectedOnce = true;
    6.         }
    7.         if (_clientDrive.GetConnectionState(_networkconnection) == NetworkConnection.State.Connecting && _clientDisConnectedOnce)
    8.         {
    9.             print("client is connecting.....");
    10.             _networkconnection = _clientDrive.Connect(_serverEndPoint);
    11.         }
    12.  
    I let the client connect first then I closed the server and I wait until the client disconnect completely, the first problem is it takes about 30 s until _clientDrive.GetConnectionState(_networkconnection) find out client has disconnected. and 30s is too much for an online multiplayer game. is there any faster way to find out the server is faced with a problem and let the client know?
    the second problem is when the client disconnected, it wouldn't reconnect with this code could you guide me on how to solve it?
     
  4. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    If your server exits gracefully, it can call
    Disconnect
    on all its active connections and the clients will be notified without delay (well, with the delay it takes for the message to make it to them).

    If your server doesn't exit gracefully (say it crashes), then the 30 seconds timeout can be reduced. With the new settings API (version 1.0.0-pre.8 or above), you can configure it in the driver like so:
    Code (CSharp):
    1. var settings = new NetworkSettings();
    2. settings.WithNetworkConfigParameters(disconnectTimeoutMS: 2000);
    3. var driver = NetworkDriver.Create(settings);
    This would set the timeout to 2 seconds.

    Is there any reason you're checking for the
    Connecting
    state in the second conditional statement? That state only occurs after calling
    Connect
    and before the connection handshake completes. Once the handshake is completed, the state becomes
    Connected
    . And once the connection fails, it becomes
    Disconnected
    .
     
    ElegantUniverse likes this.
  5. ElegantUniverse

    ElegantUniverse

    Joined:
    Sep 13, 2018
    Posts:
    78
    thank you man , that's worked perfectly.
    when server crashes the client connection will completely lost,for Reconnecting I used
    Code (CSharp):
    1.    _networkconnection = _clientDrive.Connect(_serverEndPoint);
    but it didn't work , I initialized the connection and it worked correctly.

    Code (CSharp):
    1.    var settings = new NetworkSettings();
    2.         settings.WithNetworkConfigParameters(disconnectTimeoutMS: 2000);
    3.         _clientDrive = NetworkDriver.Create(settings);
    4.         _reliablePipline = _clientDrive.CreatePipeline(typeof(ReliableSequencedPipelineStage));
    5.         _unreliablePipline = _clientDrive.CreatePipeline(typeof(UnreliableSequencedPipelineStage));
    6.         if (_clientInfo._connectToVsp)
    7.         {
    8.             IPHostEntry iPHostEntry = Dns.GetHostEntry(_clientInfo._vpsDomain);
    9.  
    10.             _serverEndPoint = NetworkEndPoint.Parse(iPHostEntry.AddressList[0].ToString(), _clientInfo._port);
    11.  
    12.         }
    13.         else
    14.         {
    15.  
    16.             _serverEndPoint = NetworkEndPoint.Parse(_clientInfo._localIp, _clientInfo._port);
    17.         }
    18.         _networkconnection = _clientDrive.Connect(_serverEndPoint);
    1. do you know a better method for reconnecting client connection when the server is live after crashing?
    2. Is there a way for the server to find out the client connection has disconnected less than 30s?
     
    Last edited: Jan 7, 2022
  6. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    Unfortunately, no. Periodically attempting to reconnect to the server is typically how it's done.
    Same way as on the client. The disconnect timeout setting can also be applied to the server. Just need to apply the setting when creating the server's driver.