Search Unity

Question What's the correct way to handle disconnects/reconnects with Lobbies/Relay/NetCode?

Discussion in 'Unity Gaming Services General Discussion' started by CameronDWills, Sep 15, 2022.

  1. CameronDWills

    CameronDWills

    Joined:
    Feb 26, 2021
    Posts:
    90
    I'm trying to dissect the UGS sample project but am having a hard time understanding the way to properly handle a player whose disconnected, and those who have disconnected but attempt to reconnect to the game. I'm using Lobbies and Relay to handle the matchmaking, and Netcode for game objects to handle the multiplayer game logic.

    I'm working on a mobile game, and what I've noticed is that disconnects seem to happen frequently, and are guaranteed to happen if the player switches from wifi to cellular data, or travels a good distance on cellular data. Here's the usecase I'm trying to accomplish:

    • When a player (host or client) detects that other player has disconnected, pause all in-game logic and actions and display a message that a player has disconnected, with a 30 seconds timer appearing as the window of time allowing the player to reconnect.

    • When a player is disconnected permanently and doesn't come back, what's the proper sequence of methods to call to shutdown the connection and lobby, so that there's no issues in trying to find a new matchmaking game? What I'm doing right now I think is overkill... not sure if it's right:
      1. First I call this method to delete the lobby:
        Code (CSharp):
        1. public async void DeleteLobby(string LobbyID){
        2.         try
        3.             {
        4.                 await LobbyService.Instance.DeleteLobbyAsync(LobbyID);
        5.                 NetworkManager.Singleton.ConnectionApprovalCallback -= ApprovalCheck;
        6.                 StopAllCoroutines();
        7.             }
        8.         catch (LobbyServiceException e)
        9.             {
        10.                 Debug.Log(e);
        11.             }
        12.  
        13.     }
      2. Then I call the NetworkManager method "Shutdown". Is this the proper way to end a game, regardless of if the player is host or client?
    • To check if a player is disconnected, right now I'm getting all of the players from the Lobby and if the count is less than 2, I know a player has disconnected (my game is only 2 players). What's the best way to go about detecting a disconnected player?

    • What methods should be used in what sequence for a disconnected player to detect they have disconnected, and then attempt to reconnect to the game they were in?

    • Is the disconnected detection instant? I'm wondering what happens if either the host or client makes an RPC call before the player is detected as disconnected... will the RPC call stay in queue until reconnection, or will it be lost? How should I handle the game logic to make sure nothing gets executed, or that anything that was executed is queued up to run when the player returns?
    Any help with any of this would be very much appreciated!
     
  2. Unity_Brandon

    Unity_Brandon

    Unity Technologies

    Joined:
    Sep 29, 2016
    Posts:
    23
    When a player (host or client) detects that other player has disconnected, pause all in-game logic and actions and display a message that a player has disconnected, with a 30 seconds timer appearing as the window of time allowing the player to reconnect.​

    This one is tricky given the nature of the service. Speaking strictly of Relay, when the host disconnects, so too are all the other clients. Likewise, there is no notification sent from the allocation service when a client disconnects.

    Luckily both of these problems can be solved by using the Lobby service. Lobby allows for host migration meaning you do not need a ton of extra code for handling the host disconnecting vs a client. You can then query the lobby service and parse the “players” array to determine when a player has disconnected. We also have status notifications for Lobby on our roadmap (connects/disconnects/etc) but no word on when that will be released quite yet.

    When a player is disconnected permanently and doesn't come back, what's the proper sequence of methods to call to shutdown the connection and lobby, so that there's no issues in trying to find a new matchmaking game? What I'm doing right now I think is overkill... not sure if it's right:​

    You're correct in deleting the Lobby. There is no need to do anything other than this since players will be (and should expect) to be disconnected. For Relay, you should send a CLOSE message and disconnect either the NetworkManager or your custom adapter. Sending the close message first isn't entirely necessary given that the connection will timeout anyways, but it's recommended.

    To check if a player is disconnected, right now I'm getting all of the players from the Lobby and if the count is less than 2, I know a player has disconnected (my game is only 2 players). What's the best way to go about detecting a disconnected player?​

    This is the correct way to do it until connect / disconnect notifications are enabled for the Lobby service.

    What methods should be used in what sequence for a disconnected player to detect they have disconnected, and then attempt to reconnect to the game they were in?​

    This depends heavily on your game logic, but generally speaking:
    1. Have a running poll for players from the Lobby service
    2. Have the non-disconnected player react when the players connected changes
    3. Have the disconnected player continuously connect to the Lobby service
    4. When (and if) connection is restored:
      1. Join the lobby
      2. Grab the Relay join code
      3. Rejoin the Relay

    Is the disconnected detection instant? I'm wondering what happens if either the host or client makes an RPC call before the player is detected as disconnected... will the RPC call stay in queue until reconnection, or will it be lost? How should I handle the game logic to make sure nothing gets executed, or that anything that was executed is queued up to run when the player returns?​

    Disconnect detections are not instant. First, the player will need to timeout of the Lobby service, then the non-disconnected player will need to poll for the missing player. NGO is not my level of expertise so as far as handling queueing and transmission during disconnects you may need to reach out on the NGO forums.

    Hopefully I was able to answer most of your questions. Please let me know if you have any others.
     
  3. ali4langi1899

    ali4langi1899

    Joined:
    Aug 30, 2020
    Posts:
    3
    Thanks for your clear explanation. I just couldn't understand one thing. If the host of the Relay disconnects, the Relay will get destroyed?

    And may I know if the steps you mentioned for reconnecting to Relay have been implemented in any official samples of UGS?