Any way to tap into OnDisconnectError?

This is in NetworkServerSimple. If you have two game instances connected to each other, and quit one of them, you have no way of handling this error (if using NetworkManager or NetworkServer, which in turn use NetworkServerSimple under the hood). Looking at the source, is there a reason why there are no handlers for these first three methods?

Basically, if a player quits their game, this generates the OnDisconnectError below instead of a timeout error, so how can you handle this on the other side? Regular, intentional, disconnections can be handled just fine.

// --------------------------- virtuals ---------------------------------------

        public virtual void OnConnectError(int connectionId, byte error)
        {
            Debug.LogError("OnConnectError error:" + error);
        }

        public virtual void OnDataError(NetworkConnection conn, byte error)
        {
            Debug.LogError("OnDataError error:" + error);
        }

        public virtual void OnDisconnectError(NetworkConnection conn, byte error)
        {
            Debug.LogError("OnDisconnectError error:" + error);
        }

        public virtual void OnConnected(NetworkConnection conn)
        {
            conn.InvokeHandlerNoData(MsgType.Connect);
        }

        public virtual void OnDisconnected(NetworkConnection conn)
        {
            conn.InvokeHandlerNoData(MsgType.Disconnect);
        }

        public virtual void OnData(NetworkConnection conn, int receivedSize, int channelId)
        {
            conn.TransportRecieve(m_MsgBuffer, receivedSize, channelId);
        }

After more testing it seems that if you terminate a game, remote clients do get a timeout error (and can handle disconnects that way), but a client disconnecting from the host doesn’t generate a timeout error for the host (you get the un-handleable OnDisconnectError above).

Does anyone know if this is a bug? Surely almost everyone out there working on a network game is trying to gracefully handle sudden disconnects?

I have noticed this on the patch notes for 5.4.1p1:

Not sure if it has something to do with what you are looking into though.

Yup, it’s definitely from that release onwards (I’m using the latest 5.5 beta). The thing is, it seems to be generated on the client when a host times out, but not the other way around, and there’s no way to intercept/handle it in that direction. Also, the source code for NetworkServerSimple.cs seems to imply that this shouldn’t happen on timeout (but in other error cases), making that patch note more confusing. :frowning:

// ...
if ((NetworkError)error != NetworkError.Timeout)
{
    m_Connections[connectionId] = null;
    if (LogFilter.logError) { Debug.LogError("Server client disconnect error:" + connectionId); }

    //NOTE: timeout should not generate a disconnect error
    OnDisconnectError(conn, error);
    return;
}
//...

Not sure if it is a bug, but I am facing the same “problem”. Before the patch it was working fine. Now, when players quits the game, i get this same error and none of my override functions is fired on NetworkManager.
If some knows a workaround or a solution, please let me know.

1 Like

Argh! Just came across this thing too. Annoyingly 5.4.1p1 fixes a different UNET showstopper, but then introduces this one!

Has anyone submitted a bug report on this, otherwise i’ll add one.

Guys , this is a bug. I submitted one before for all Disconnects and that got fixed, 5.3ish times. This should not happen. Make a small reproducible and send it with the bug.

There haven’t been any networking fixes in the last few beta releases. I hope the next one will have a bunch.

I can confirm the bug! Installed the 5.4.1p3 and getting errors. Probably all started in patch 1.
Going to reinstall without patches to see what happens…

I would really love to release the first online-enabled version of my game to my Kickstarter backers and alpha customers, but this is one issue that is holding me back at the moment. Anyone hosting can’t be notified of a client that quit, aside from a downward spiral of Unity errors and network failures from that point on. :frowning:

Encountered this in uMMORPG too. Reported it as #838689.

I created a test scene with just a NetworkManager and a player prefab for the bug report, it happens without any scripts or any fancy features.

1 Like

From the advice of another Unet developer, I tried tapping into Application.logMessageReceived to capture the Debug error logs from NetworkServerSimple to catch this case (really hacky), but the log handler doesn’t appear to be called for any Debug messages. Is this another 5.5 bug?

We can literally see right where the problem is in the code on Github, but have no control over a fix. :frowning:

Mind sharing the link?

Oh it’s the same code I showed in the first post. NetworkServerSimple (used by NetworkServer) simply Debug.Logs an error instead of running it through a handler that you can catch. Here’s all the source… but I don’t know if it’s the latest or not. I made a mistake, it’s on Bitbucket:

https://bitbucket.org/Unity-Technologies/networking/src/3610ab4e4c0f2a3d74bb3d005641e11201c7e6f3/Runtime/

1 Like

Any time I disconnect a client the server dumps a

Server client disconnect error:1

followed by an endless stream of

Send Error: WrongConnection channel:1 bytesToSend:1390
ChannelBuffer SendBytes no space on unreliable channel 1
SendBytesToReady failed for...
Failed to send internal buffer channel:1 bytesToSend:1395

and the client object never gets destroyed. Is this the same error you are all encountering? This does not happen in 5.4.0.

Yup, this is the new error, preventing a clean way of handling the case where the client disconnects. Another developer pointed me in a direction that lets you workaround this, though it’s a pretty hacky bandaid. Basically, you can register a callback handler to listen for Debug.Log messages:

Application.logMessageReceived += HandleLog;

Then in your handler, you can catch that specific Unet error log and handle the disconnect:

void HandleLog(string logString, string stackTrace, LogType type)
    {
        if (type != LogType.Error)
        {
            return;
        }

        string[] errorParts = logString.Split(':');
        switch (errorParts[0])
        {
            case "Server client disconnect error, connectionId":
                // handle stuff
                break;
            case "OnDisconnectError error":
                // handle stuff
                break;
        }
    }

This is a pretty bad way to handle this, and I still don’t know why this super common case is not passed through a proper handler in 5.5.

1 Like

Just checked it with todays 5.4.2f1 - it’s still broken.

@shadiradio : Thank you for the “hacky” workaround :smile:

In my current app it’s a common situation that server and/or client get disconnected from the network. The last version with functional disconnect behaviour seems to be 5.4.1f1.

Thanks for sharing.

I found that this error only seems to occur on when the application quits without a clean networking disconnect. I added the following to my player script and the errors went away on the server:

void OnApplicationQuit(){
    if(isLocalPlayer) {
        NetworkManager.singleton.StopClient ();
    }
}

I also submitted a bug report (with example) so hopefully they’ll get it up on the issue tracker shortly.

2 Likes