Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question How to detect when a disconnection has happened?

Discussion in 'NetCode for ECS' started by EmmaPrats, Jan 17, 2023.

  1. EmmaPrats

    EmmaPrats

    Joined:
    Apr 19, 2019
    Posts:
    8
    1. Detecting disconnection from Client in the Server

    Is there a callback I can listen to?

    I know that when a client disconnects, its "NetworkConnection" entity (the one that has a
    NetworkIdComponent
    ) is destroyed in the Server World. Clearly, Netcode for Entities does detect when a client disconnects. How can my server's logic detect that too?

    I am aware that there is a "proper" way to disconnect with NetworkStreamRequestDisconnect. I don't want to rely on that, if the client crashes or the player kills the game's process I want to know that they disconnected.

    2. Detecting disconnection from Server in the Client

    What is the appropriate way?

    Thank you for your help!
     
  2. NikiWalker

    NikiWalker

    Unity Technologies

    Joined:
    May 18, 2021
    Posts:
    306
    Hey Emma,

    Yes, you can track both connections and disconnections via the optional `ConnectionState` `ICleanupComponentData`.

    "PlayerList" is a new sample showing this feature off, found here: https://github.com/Unity-Technologi...ster/NetcodeSamples/Assets/Samples/PlayerList
    This sample uses RPCs to create a "feed" of players who have connected/disconnected.
    One other approach (which isn't demonstrated here) is to implement this behaviour via a static-optimized ghost (with an IBufferElementData containing all connected players).

    For this implementation, take a look at the server logic here: https://github.com/Unity-Technologi.../Samples/PlayerList/ServerPlayerListSystem.cs

    ConnectionState is added on like 67, where we have a query of all new `NetworkStreamConnection` entities, where we add the optional component.

    New joiners are handled in the `HandleNewJoinersJob` on line 101. We wait for a client to send an RPC containing their `Username`. Thus, each client must opt-into being seen in the player list. Obviously, for your own game, you can source usernames however you like. E.g. The GameServer could communicate with a backend instead.

    For disconnecting players (regardless of disconnect reason): The `NotifyPlayersOfDisconnectsJob` job on line 184 will show you the query, and how it's used to detect disconnects.

    The `ClientPlayerListSystem`:
    • Registers a username with the "PlayerList" sub-system.
    • Receives these "PlayerList" change events.
    • Uses a cache of this data to draw the Player List, and all NOTIFICATIONS (via IMGUI).

    You can also use new controls in the "Multiplayer > Window: PlayMode Tools" to test various forms of disconnect. The next few pre-releases will contain improvements to this window.
     
    Last edited: Jan 17, 2023
  3. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    115
    Nice, this was really helpful.

    To continue talk about disconnections, is there a particular reason why ALL ghost entities are automatically destroyed on clients if the server disconnects? Is there a way to keep them, so I can kill the game gracefully? At the moment, because a lot of the visuals are made of ghosted entities, the world disppearing is very jarring, and I don't particularly want to hard-cut to a fullscreen "connection lost" popup to hide it.
     
  4. NikiWalker

    NikiWalker

    Unity Technologies

    Joined:
    May 18, 2021
    Posts:
    306
    Supporting 'reconnecting with existing state' is a non-trivial feature that we simply haven't had time to build yet. It's on our radar, but feature-work likely won't start for a long time. If you need this, you'll need to roll it yourself via a package fork.

    Unfortunately not easily, but again it's on our radar.

    If you only want to keep them (but not reconnect with this cached state), you can probably hack in a thing that prevents those ghosts from succeeding the delete query. My guess (not at PC) is to remove the `GhostInstance` component when you detect a disconnect.
     
  5. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    115
    I'm still not sure what the reason is for deleting ghost entities when disconnected, but removing GhostInstance does the trick. Many thanks!
     
    NikiWalker likes this.
  6. NikiWalker

    NikiWalker

    Unity Technologies

    Joined:
    May 18, 2021
    Posts:
    306
    It's only in case you reconnect. Doing so - with 'stale' ghosts already spawned on the client - would confuse netcode and lead to unknown/undefined behaviour.
     
    Richay likes this.