Search Unity

What's the proper way to handle disconnections in UNET?

Discussion in 'UNet' started by firestorm713q, Feb 4, 2016.

  1. firestorm713q

    firestorm713q

    Joined:
    Jan 6, 2013
    Posts:
    16
    I'm making a two player card game using the matchmaker, and I can't figure out how to properly delete matches from the matchmaker, and how to handle a case like when the user creates a match and then changes their mind and backs out to the create match dialogue (implemented as a panel that I enable and disable).
    Here's what I've tried so far:
    Code (CSharp):
    1. public void DisconnectFromNetwork()
    2.     {
    3.         numUsers = 0;
    4.         if (isHost)
    5.         {
    6.             Debug.LogError("Destroying Host!");
    7.             string newName = matchName + "-DISCONNECTED";
    8.             matchName = newName;
    9.             matchMaker.DestroyMatch((UnityEngine.Networking.Types.NetworkID)MatchNetworkID, OnDestroyMatch);
    10.             StopHost();
    11.             //StopMatchMaker();
    12.         }
    13.         else
    14.         {
    15.             DropConnectionRequest dropReq = new DropConnectionRequest();
    16.             dropReq.networkId = (UnityEngine.Networking.Types.NetworkID)MatchNetworkID;
    17.             dropReq.nodeId = (UnityEngine.Networking.Types.NodeID)MatchNodeID;
    18.             matchMaker.DropConnection(dropReq, OnConnectionDrop);
    19.         }
    20.         StopClient();
    21.     }
    22.  
    23.     public new void StopClient()
    24.     {
    25.         OnStopClient();
    26.  
    27.         if (LogFilter.logDebug) { Debug.Log("NetworkManager StopClient"); }
    28.         isNetworkActive = false;
    29.         if (client != null)
    30.         {
    31.             // only shutdown this client, not ALL clients.
    32.             client.Disconnect();
    33.             client.Shutdown();
    34.             client = null;
    35.         }
    36.         StopMatchMaker();
    37.  
    38.         ClientScene.DestroyAllClientObjects();
    39.  
    40.         if(SceneManager.GetActiveScene().name == "Single-Multiplayer-Scene")
    41.         {
    42.             SceneManager.LoadScene("MainMenu");
    43.         }
    44.     }
    DisconnectFromNetwork() is a function called when the user clicks on the "back to multiplayer menu" button. isHost is a variable I set when the host is started. I also populate the MatchNetworkID and MatchNodeIDs from the OnMatchCreate and OnMatchJoin functions respectively. I'm hiding the StopClient() function because I want to fine tune the behavior for when the player disconnects from mid-game.

    The specific errors I'm getting are:
    1:
    This error occurs when I try to recreate a match. Digging through the source, it appears this message happens when a client scene is set to ready, and the network manager attempts to set another scene as ready. It's supposed to be set to false when the client disconnects, but that doesn't appear to be happening.
    2:
    This error occurs when the player joins a match they're already in.

    So my general question is: How do I avoid these errors? Especially the one when I try to recreate a match on the host. Or am I once again going about things the completely wrong way.
     
    Anisoropos likes this.
  2. Gorgor

    Gorgor

    Joined:
    Apr 28, 2012
    Posts:
    51
    +1 THIS!!! : "ArgumentException: An element with the same key already exists in the dictionary."

    Good question. Trying to solve this for over half a year. Good luck.
     
  3. Stephen_O

    Stephen_O

    Joined:
    Jun 8, 2013
    Posts:
    1,510
    You have to create a custom callback on your join match request to avoid the error until it's fixed for 5.4 . I found this https://issuetracker.unity3d.com/issues/matchmaker-cant-re-join-a-match-after-leaving and a user shared his method in the comments. It worked for me, this is what I did to be able to have a client enter/exit a lobby match without causing the dictionary error.

    Back button to leave a match
    Code (CSharp):
    1. if (lobbyHUDReference.startGameButton.activeInHierarchy) {
    2.     networkLobbyManager.matchMaker.DestroyMatch ((NetworkID)networkLobbyManager.matchInfo.networkId, OnDestroyMatch);
    3.     networkLobbyManager.StopHost();
    4.     networkLobbyManager.StopMatchMaker();
    5.     Debug.Log ("Destroy Match");
    6. } else {
    7.     networkLobbyManager.StopClient();
    8.     networkLobbyManager.StopMatchMaker();
    9.     Debug.Log ("Leave Match");
    10. }

    Join match with custom callback
    Code (CSharp):
    1. networkLobbyManager.matchMaker.JoinMatch(networkId, string.Empty, new NetworkMatch.ResponseDelegate<JoinMatchResponse>(MatchJoined));

    Custom joinMatch callback
    Code (CSharp):
    1. public virtual void MatchJoined(JoinMatchResponse matchInfo){
    2.     if(LogFilter.logDebug){
    3.         Debug.Log ("Network Manager OnMatchJoined");
    4.     }
    5.     if (matchInfo.success) {
    6.         try {
    7.             Utility.SetAccessTokenForNetwork (matchInfo.networkId, new NetworkAccessToken (matchInfo.accessTokenString));
    8.         } catch (System.ArgumentException ex) {
    9.             if (LogFilter.logError) {
    10.                 //Debug.LogError (ex);
    11.             }
    12.         }
    13.         networkLobbyManager.StartClient (new MatchInfo (matchInfo));
    14.     }
    15.     else if(LogFilter.logError) {
    16.         Debug.LogError (string.Concat("Join Failed:", matchInfo));
    17.     }
    18. }
     
    thegreatzebadiah and Chom1czek like this.
  4. Anisoropos

    Anisoropos

    Joined:
    Jul 30, 2012
    Posts:
    102
    @firestorm713q did you ever manage to fix the problem of : Creating a match -> Leaving -> Creating a new match?