Skip to content

fix: Disconnect event notifications #2390 #3551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: develop-2.0.0
Choose a base branch
from

Conversation

NoelStephensUnity
Copy link
Collaborator

@NoelStephensUnity NoelStephensUnity commented Jul 17, 2025

This is a work in progress fix for issue #2390.

The fix is to provide a way for a NetworkTransport derived class implementation can register disconnect event maps to a standardized set of disconnect event types. This PR includes modifications to UnityTransport so it registers its internal disconnect events with the generic ones.

WIP
Note: I might take most of what was implemented in the NetworkTransport and migrate that to a different class that could be applied to a NetworkTransport derived class. (open to suggestions on this approach)

MTTB-1345

Changelog

  • Added: (wip on all that was added)
  • Fixed: Issue where the disconnect event and provided message was too generic to know why the disconnect occurred.

Testing and Documentation

  • No tests have been added.
  • Includes unit tests.
  • Includes integration tests (wip)
  • No new documentation required.
    • When we create documentation on creating your own custom NetworkTransport, this should be included.

Backport

TBD if we want to bring all of this into v1.x.

This update is a work in progress resolution to the issue where disconnect event notifications were too vague and did not provide any way to know what the cause of the disconnect was.
Adding some final adjustments and (hopefully) improving the disconnect event messaging upon a local client or server shutting down.
When using NotMeRpc, make sure we only send to connected clients and not the service to avoid infinite spamming of the RPC.
Adding additional comments and disconnect event specific messages for UnityTransport.
Missed a parameter in the XML-API
@simon-lemay-unity
Copy link
Contributor

My initial reaction to this is that it seems complex for what it is.

Why couldn't we just impose on the NetworkTransport to use NGO's enum when setting a disconnect reason? That is, only add SetDisconnectEvent(DisconnectEvents disconnectEvent, string message = null) to the NetworkTransport API. Every transport can then do its own mapping internally in the way it makes the most sense for it (possibly in a more efficient way than by maintaining a dictionary on the side just for that).

I'm not sure I see the point of having all that mapping machinery in NetworkTransport. Plus, it kinda bakes the idea that a transport's disconnect reason will be a byte (or even just a numerical value) directly in the API. That's true for UnityTransport, but might not be the case for other transports. Say if a transport has their backend returning strings explaining the disconnect reason, then all of that mapping machinery is basically useless for them. They'll end up doing their own mapping of strings to disconnect events directly in their transport.

Fixing some minor test issues after the disconnect notification updates.
@NoelStephensUnity
Copy link
Collaborator Author

My initial reaction to this is that it seems complex for what it is.

Why couldn't we just impose on the NetworkTransport to use NGO's enum when setting a disconnect reason? That is, only add SetDisconnectEvent(DisconnectEvents disconnectEvent, string message = null) to the NetworkTransport API. Every transport can then do its own mapping internally in the way it makes the most sense for it (possibly in a more efficient way than by maintaining a dictionary on the side just for that).

I'm not sure I see the point of having all that mapping machinery in NetworkTransport. Plus, it kinda bakes the idea that a transport's disconnect reason will be a byte (or even just a numerical value) directly in the API. That's true for UnityTransport, but might not be the case for other transports. Say if a transport has their backend returning strings explaining the disconnect reason, then all of that mapping machinery is basically useless for them. They'll end up doing their own mapping of strings to disconnect events directly in their transport.

The approach you describe above I actually started with, but then I realized that I would have to decorate all places that implement the feature/update with UTP_TRANSPORT_2_4_ABOVE. Which would mean any custom NetworkTransport would have no way of having messages handled without including com.unity.transport. The higher abstraction ensures that any NetworkTransport derived class can provide a map to the "universal disconnect events" based on the values the transport in question provides.

Otherwise, users would always have to:

  • Include com.unity.transport
  • Replicate a chunk of the "mapping" code in this PR to map the transport they are adding to the UTP disconnect events.

This way, it keeps the notification "transport neutral" while providing some mechanism to register a transport's disconnect events to the NGO (standardized) disconnect events.

Does this make more sense?

Updating the multi-client test.
@simon-lemay-unity
Copy link
Contributor

Does this make more sense?

Not really. Maybe I'm missing something obvious, but I don't see how UTP would be required.

To be clear, my suggestion is not for the disconnection events in NetworkTransport to be UTP's. I'm proposing that NGO has its own enum for disconnection events (like it does in this PR), but that the only API in NetworkTransport be to signal those NGO disconnection events, and not provide any mapping machinery. If there's a need for a mapping between those NGO events and the transport's, then that mapping should be in the transport itself.

Basically my proposal would be:

abstract class NetworkTransport
{
    public enum DisconnectEvents
    {
        ...
    }

    public DisconnectEvents DisconnectEvent { get; protected set; }
    public string DisconnectEventMessage { get; protected set; }
}

public class UnityTransport
{
    ...
    case TransportEvent.Disconnect:
        ...
        switch (reader.ReadByte())
        {
            case (byte)Error.Timeout:
                DisconnectEvent = DisconnectEvents.ProtocolTimeout;
                DisconnectEventMessage = "Connection has timed out.";
            ...
        }
}

And while I get the argument that we don't want every transport to have to implement mapping logic, I don't agree with it. The mapping logic will normally be simple enough that I don't believe it's worth abstracting away in NetworkTransport. In the case of UnityTransport, it can be as simple as a switch statement. And it's not like the switch statement is more verbose or anything; the current proposal has basically the same amount of code required to set up the mappings through the generic mechanism.

@NoelStephensUnity
Copy link
Collaborator Author

the same amount of code required to set up the mappings through the generic mechanism.

Yeah...you have a good point about the amount of code and I wasn't 100% happy with my initial approach anyway.... I will tinker around with it and see if we can keep some of the non-event type related script while approaching it the way you described above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants