Search Issue Tracker

Won't Fix

Won't Fix in 1.0.X

Votes

1

Found in [Package]

1.0.0-pre.4

1.0.0-pre.5

Issue ID

NCCBUG-128

Regression

No

[Netcode] Netcode not calling the method when closing built client

Package: Multiplayer Netcode for GameObjects

-

Reproduction steps:
1. Open the attached project "NetCode_Disconnect_Bug.zip"
2. Start three instances of the provided build in the Builds folder and redirect the log file, example PowerShell command: .\\NetCode_Disconnect_Bug.exe -logfile .\\log1.log ; & .\\NetCode_Disconnect_Bug.exe -logfile .\\log2.log ; & .\\NetCode_Disconnect_Bug.exe -logfile .\\log3.log
3. Make one as host or server, the others as clients via the buttons in the top left corner
4. Observe the number rising the more clients connect (3 if host, 2 if server)
5. Close one of the clients (not the host). The number does not change.
6. Close the second client. The number decreases by one (2 if host, 1 if server)
7. View the log of each client and host

Expected result: The host and the client receives the OnClientDisconnected messages
Actual result: The host receives the OnClientDisconnected messages, the client who is closed does not.

Reproducible with: 1.0.0-pre.4 (2021.2.13f1), 1.0.0-pre.5(2022.1.0b9, 2022.2.0a5)
Could not test with: 1.0.0-pre.4 (2019.4.36f1, 2020.3.30f1)( Multiple project errors when downgraded)

  1. Resolution Note:

    There are no fixes planned for this Bug

  2. Resolution Note (1.0.X):

    This issue is caused by the order of operations.
    The connected client list is not updated on the server until the OnClientDisconnected callback is invoked. This was intentional as a user might still want to gather information from the connected client list about the disconnected client.

Comments (1)

  1. ashwinimurthy

    Jun 13, 2022 20:51

    The issue you are running into has to do with order of operations.

    Within NetworkManager.HandleRawTransportPoll where it is handling the transport disconnect event:

    case NetworkEvent.Disconnect:
    #if DEVELOPMENT_BUILD || UNITY_EDITOR
    s_TransportDisconnect.Begin();
    #endif
    clientId = TransportIdCleanUp(clientId, transportId);

    if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
    {
    NetworkLog.LogInfo($"Disconnect Event From {clientId}");
    }

    OnClientDisconnectCallback?.Invoke(clientId); <--- the client disconnected callback is invoked

    if (IsServer)
    {
    OnClientDisconnectFromServer(clientId); <----- this is where the disconnected client's keypair entry is removed
    }
    This specific order of operations was from a previous bug where a user still wanted to access the disconnected client's NetworkClient from the ConnectedClients dictionary.

    The issue with the code:

    protected virtual void OnClientDisconnect(ulong clientId)
    {
    if (IsServer)
    {
    Debug.Log($"Server: Disconnected {clientId}");
    UpdateTextConnectedAmountClientRpc(NetworkManager.Singleton.ConnectedClients.Count);
    UpdateTextMaxAmountClientRpc(NetworkManager.Singleton.ConnectedClients.Count);
    }
    }
    It is using the full count of the ConnectedClients dictionary
    So, the two ways to do this and always get the right count:
    * Subtract 1 from the total connected clients list

    - Or optionally filter out the client id for the client that was disconnected from that list (i.e. use Linq Where or the like)
    - Set a bool on the server side that during the update (server-side) if the bool is set it sends the updated count via RPC
    - By the time the update is invoked, the connected client dictionary count will reflect the correct value.

    We will better document that on the server side the disconnected client's ConnectedClients keypair entry will still exist upon the OnClientDisconnected being invoked.

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.