Skip to content
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

fix: ObjectDisposedException on Unity Transport shutdown [backport] #3152

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Fixed

- Fixed issue where an exception was thrown when calling `NetworkManager.Shutdown` after calling `UnityTransport.Shutdown`. (#3118)
- Fixed issue where a newly synchronizing client would be synchronized with the current `NetworkVariable` values always which could cause issues with collections if there were any pending state updates. Now, when initially synchronizing a client, if a `NetworkVariable` has a pending state update it will serialize the previously known value(s) to the synchronizing client so when the pending updates are sent they aren't duplicate values on the newly connected client side. (#3126)
- Fixed issue where changing ownership would mark every `NetworkVariable` dirty. Now, it will only mark any `NetworkVariable` with owner read permissions as dirty and will send/flush any pending updates to all clients prior to sending the change in ownership message. (#3126)
- Fixed issue with `NetworkVariable` collections where transferring ownership to another client would not update the new owner's previous value to the most current value which could cause the last/previous added value to be detected as a change when adding or removing an entry (as long as the entry removed was not the last/previously added value). (#3126)
Expand Down Expand Up @@ -209,7 +210,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
### Added

- Added a protected virtual method `NetworkTransform.OnInitialize(ref NetworkTransformState replicatedState)` that just returns the replicated state reference.

### Fixed

- Fixed issue where invoking `NetworkManager.Shutdown` within `NetworkManager.OnClientStopped` or `NetworkManager.OnServerStopped` would force `NetworkManager.ShutdownInProgress` to remain true after completing the shutdown process. (#2661)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,11 @@ public override bool StartServer()
/// </summary>
public override void Shutdown()
{
if (NetworkManager && !NetworkManager.ShutdownInProgress)
{
Debug.LogWarning("Directly calling `UnityTransport.Shutdown()` results in unexpected shutdown behaviour. All pending events will be lost. Use `NetworkManager.Shutdown()` instead.");
}

if (m_Driver.IsCreated)
{
// Flush all send queues to the network. NGO can be configured to flush its message
Expand All @@ -1461,6 +1466,7 @@ public override void Shutdown()
DisposeInternals();

m_ReliableReceiveQueues.Clear();
m_State = State.Disconnected;

// We must reset this to zero because UTP actually re-uses clientIds if there is a clean disconnect
m_ServerClientId = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,5 +517,42 @@ public IEnumerator ReliablePayloadsCanBeLargerThanMaximum()

yield return null;
}

public enum AfterShutdownAction
{
Send,
DisconnectRemoteClient,
DisconnectLocalClient,
}

[UnityTest]
public IEnumerator DoesNotActAfterShutdown([Values] AfterShutdownAction afterShutdownAction)
{
InitializeTransport(out m_Server, out m_ServerEvents);
InitializeTransport(out m_Client1, out m_Client1Events);

m_Server.StartServer();
m_Client1.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);

m_Server.Shutdown();

if (afterShutdownAction == AfterShutdownAction.Send)
{
var data = new ArraySegment<byte>(new byte[16]);
m_Server.Send(m_Client1.ServerClientId, data, NetworkDelivery.Reliable);
}
else if (afterShutdownAction == AfterShutdownAction.DisconnectRemoteClient)
{
m_Server.DisconnectRemoteClient(m_Client1.ServerClientId);

LogAssert.Expect(LogType.Assert, "DisconnectRemoteClient should be called on a listening server");
}
else if (afterShutdownAction == AfterShutdownAction.DisconnectLocalClient)
{
m_Server.DisconnectLocalClient();
}
}
}
}
Loading