Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do I detect on the client that I was disconnected?

Discussion in 'Multiplayer' started by Lohoris2, Jan 18, 2016.

  1. Lohoris2

    Lohoris2

    Joined:
    Aug 20, 2013
    Posts:
    85
    Somehow I can't find how am I supposed to detect in the client when I'm disconnected (either explicitly, or because the server just crashed).

    Neither of the following functions ever gets called:
    • OnClientError
    • OnClientDisconnect
    • OnClientNotReady
    • OnDisconnectedFromServer
    • RegisterHandler(MsgType.Error
    • RegisterHandler(MsgType.Disconnect


    I will just get random ReadByte errors after a little while, instead.

    So… what would I be supposed to do?
     
  2. Lohoris2

    Lohoris2

    Joined:
    Aug 20, 2013
    Posts:
    85
    Guys?
    This is one of the most basic features that EVERY SINGLE networking program needs…
    Can I get an answer, please?
    Really.
     
  3. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,732
    What networking system are you using? With UNET I use this and it does the job
    http://docs.unity3d.com/ScriptReference/Network.OnDisconnectedFromServer.html

    I also use these overrides in my custom NetworkManager

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.Networking;
    5.  
    6. public class MyNetworkManager : NetworkManager {
    7.  
    8.     public override void OnServerDisconnect (NetworkConnection conn)
    9.     {
    10.         base.OnServerDisconnect (conn);
    11.     }
    12.  
    13.     public override void OnClientDisconnect (NetworkConnection conn)
    14.     {
    15.         base.OnClientDisconnect (conn);
    16.     }
    17. }
     
  4. Lohoris2

    Lohoris2

    Joined:
    Aug 20, 2013
    Posts:
    85
    But… I'm using UNET, and I already told that these aren't getting called on my client… that's what I told in the first post… : /
     
    Last edited: Jan 27, 2016
  5. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,110
    Network.OnDisconnectedFromServer is for old unity multiplayer raknet and doesn't work with uNet and the problem is real.
     
  6. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,732
    I apologise you are right I used OnDisconnectedFromServer in a pre UNET project.

    However, I'm using NetworkManager.OnServerDisconnect in a two player on line game I'm currently working on. I use it to detect that the 2nd player has disconnected (either explicitly or from a time out or crash) so that the host can be closed and return to the offline scene.

    If the host disconnects or crashes then the network manager automatically loads the offline scene on the non-host player after a couple of seconds, so I don't need to explicitly check for that.

    Maybe there is a problem for some use cases, but it works for me, which is why I suggested using the overrides. (Although I'm only using one of them in fact.)
     
  7. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,260
    I am currently experiencing this same issue.

    overriding OnClientDisconnect does not fire at all. Log messages do get fired when log is set to debug.

    It was working at first for me. Then I started to make a custom manager that I could handle fading scenes in and out with.

    If I create a new project everything is fine and works as it should. I am going to try and create a custom manager in the new project and see if I can recreate the problem.
     
    wlwl2 likes this.
  8. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    529
    Here is what i use with UNET and it works fine, are you using the same methods or something else?

    I made my own NetworkManager Script with : NetworkManager as base

    So you want to know if a client disconnected from the sever?
    Then you have to override public override void OnServerDisconnect(NetworkConnection conn)
    this is called on the server when a client disconnects and you can find out which client disconnected in the conn parameter.
     
  9. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,732
    That's what I found to be the case too. However since this thread was started I've done some further testing and it seems that if the host disconnects or crashes the other clients do not receive any notification, OnClientDisconnect() doesn't seen to fire under any circumstances.

    This didn't cause me a problem in this case however, as the NetworkManager automatically loads the offline scene on the client after the host times out. But I can see if you aren't using that automatic behaviour it could cause problems.
     
  10. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,260
    I want the game to return to the offline scene on the clients when the host disconnects. It isn't doing it as it should which is automatically. If I create my own custom manager or use the default one it still doesn't change the scene. With a custom manager I override OnClientDisconnect which informs a client that the server has been disconnected. This does not get called and the scene remains the same with the host player still in the scene. No matter which way I try it won't change to the offline scene.

    In my test scene that is working it fires every time, no matter which way the host gets disconnected. In my project where the problem is happening it doesn't time out it doesn't even recognize that the host has disconnected at all indefinitely. As I write this I disconnected the host 10 mins ago and the client still has yet to register the host disconnecting.
     
  11. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    529
    Which Disconnect Timeout value did you set in your project NetworkManager?
     
  12. Lohoris2

    Lohoris2

    Joined:
    Aug 20, 2013
    Posts:
    85
    2000ms here.

    And no, it doesn't automatically load the offline scene, it just keeps complaying it can't send since the network is down…

    here it complains during a NetworkMessage.ReadMessage:

    NullReferenceException: Object reference not set to an instance of an object
    UnityEngine.Networking.NetworkReader.ReadByte () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:161)
    UnityEngine.Networking.NetworkReader.ReadPackedUInt32 () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:61)
    UnityEngine.Networking.NetworkReader.ReadNetworkId () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:151)
    xxxxxx.CharIdMessage.Deserialize (UnityEngine.Networking.NetworkReader reader)
    UnityEngine.Networking.NetworkMessage.ReadMessage[CharIdMessage] () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/UNetwork.cs:161)
    xxxxxx.Client.HandleChar (UnityEngine.Networking.NetworkMessage msg) (at Assets/sources/NetworkNew/Client.cs:309)
    UnityEngine.Networking.NetworkConnection.InvokeHandler (Int16 msgType, UnityEngine.Networking.NetworkReader reader, Int32 channelId) (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:197)
    UnityEngine.Networking.NetworkConnection.InvokeHandlerNoData (Int16 msgType) (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:179)
    UnityEngine.Networking.NetworkClient.Update () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:666)
    UnityEngine.Networking.NetworkClient.UpdateClients () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:861)
    UnityEngine.Networking.NetworkIdentity.UNetStaticUpdate () (at /Users/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:1044)

    Then it complains everytime I try to [Command]:

    Send command attempted with no client running [client=hostId: 0 connectionId: 1 isReady: True channel count: 2].
    UnityEngine.Networking.NetworkBehaviour:SendCommandInternal(NetworkWriter, Int32, String)
    xxxxxx.Client:CallCmdAction(Direction, Boolean, Boolean)
    xxxxxx.Client:Update() (at Assets/sources/NetworkNew/Client.cs:260)

    Obviously manually trapping every single call is ugly, bad, wrong, and stupid since this should be the job of those callbacks which aren't working…
     
  13. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,260
    For me the timeout is 2000 ms as well. Something bugged in my project, only certain events get triggered. I get no error messages at all. With the log level set to debug, it does output client disconnected on the console but nothing happens.
     
  14. OmarMoya

    OmarMoya

    Joined:
    Apr 26, 2014
    Posts:
    6
    Ok guys, i mannaged some of the errors that can occur at the NetworkManager. When you implement your own NetworkManager, inheriting from it, you have to make your own Start Host function, for example, calling NetworkManager.singleton.StartHost(). That function returns a NetworkClient. Having that client, you can add handlers to it that are called depending of the type of the message. For example:

    Code (CSharp):
    1.  
    2. public void StartHostClick () {
    3.     NetworkClient wc = NetworkManager.singleton.StartHost ();
    4.  
    5.     if (wc != null) {
    6.         wc.RegisterHandler (MsgType.Disconnect, OnDisconnectClient);
    7.         wc.RegisterHandler (MsgType.Error, OnErrorClient)
    8.     }
    9. }
    10.  
    11. public void OnErrorClient (NetworkMessage netMsg) {
    12.     print("Client connection error! ");
    13. }
    14.  
    15. public void OnDisconnectClient (NetworkMessage netMsg) {
    16.     print("Client disconnected! ");
    17. }
    the same happens with NetworkClientwc=NetworkManager.singleton.StartClient();

    What i dont know how to do, is getting, for example, the reason of the disconnection. Could be from an error, or time out, idk...
     
  15. infuzo

    infuzo

    Joined:
    Aug 22, 2013
    Posts:
    66
    You can create coroutine where you check "NetworkManager.singleton.client.isConnected".