Skip to content

Commit 5e8e7e7

Browse files
fix: raise the client's own disconnect event when a hybrid client disconnects
UnifiedNetcodeTransport.DisconnectLocalClient only requested the N4E disconnect. N4E reports it later, after NGO's shutdown has stopped listening, so the disconnecting client never received its ClientDisconnected event. It now notifies immediately, as UnityTransport does, and ignores N4E's later event. A server-initiated disconnect removes the connection before notifying, so the shutdown it triggers does not notify a second time. DisconnectTests and PeerDisconnectCallbackTests now run in hybrid prefab mode.
1 parent d4fda26 commit 5e8e7e7

3 files changed

Lines changed: 46 additions & 6 deletions

File tree

‎com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,11 @@ private class ConnectionInfo
221221

222222
internal void DispatchMessage(int connectionId, in FixedBytes1280 buffer)
223223
{
224-
var connectionInfo = m_Connections[connectionId];
224+
// The connection is removed on disconnect, which can be ahead of its last messages.
225+
if (!m_Connections.TryGetValue(connectionId, out ConnectionInfo connectionInfo))
226+
{
227+
return;
228+
}
225229

226230
using var arr = FixedBytes1280.ToNativeArray(buffer);
227231
var reader = new DataStreamReader(arr);
@@ -374,6 +378,8 @@ private void OnClientDisconnectFromServer(Connection connection, NetcodeConnecti
374378
GetDisconnectEventFromNetworkStreamDisconnectReason(connectionEvent.DisconnectReason),
375379
GetDisconnectMessageFromNetworkStreamDisconnectReason(connectionEvent.DisconnectReason)
376380
);
381+
// Removed before notifying, so the shutdown this triggers does not notify again from DisconnectLocalClient.
382+
m_Connections.Remove(connectionEvent.Id.Value);
377383
InvokeOnTransportEvent(NetworkEvent.Disconnect, (ulong)connectionEvent.Id.Value, default, m_RealTimeProvider.RealTimeSinceStartup);
378384
}
379385

@@ -440,7 +446,7 @@ public override void DisconnectRemoteClient(ulong clientId)
440446
public override void DisconnectLocalClient()
441447
{
442448
// Remove the connection 1st (the world might not be available)
443-
m_Connections.Remove((int)ServerClientId);
449+
var wasConnected = m_Connections.Remove((int)ServerClientId);
444450

445451
// TODO-FIX-REVIEW-ME:
446452
// This was causing errors to occur upon shutdown during an integration test.
@@ -462,6 +468,13 @@ public override void DisconnectLocalClient()
462468
}
463469
m_NetworkManager.NetcodeWorld.RequestDisconnectFromServer();
464470

471+
// N4E reports the disconnect a frame or more later, after NGO's shutdown has stopped listening, so the
472+
// client would never be notified. Notify now, as UnityTransport does, and ignore N4E's later event.
473+
m_NetworkManager.NetcodeWorld.OnConnectionEvent -= OnClientConnectionEvent;
474+
if (wasConnected)
475+
{
476+
InvokeOnTransportEvent(NetworkEvent.Disconnect, ServerClientId, default, m_RealTimeProvider.RealTimeSinceStartup);
477+
}
465478
}
466479

467480
public override ulong GetCurrentRtt(ulong clientId)
@@ -479,7 +492,12 @@ public override void Initialize(NetworkManager networkManager = null)
479492

480493
public override void Shutdown()
481494
{
482-
495+
var netcodeWorld = m_NetworkManager != null ? m_NetworkManager.NetcodeWorld : null;
496+
if (netcodeWorld != null)
497+
{
498+
netcodeWorld.OnConnectionEvent -= OnClientConnectionEvent;
499+
netcodeWorld.OnConnectionEvent -= OnServerConnectionEvent;
500+
}
483501
}
484502
}
485503
}

‎com.unity.netcode.gameobjects/Tests/Runtime/Connection/DisconnectTests.cs‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@ namespace Unity.Netcode.RuntimeTests
1919
/// - When <see cref="OwnerPersistence.DestroyWithOwner"/> the server-side player object is destroyed
2020
/// - When <see cref="OwnerPersistence.DontDestroyWithOwner"/> the server-side player object ownership is transferred back to the server
2121
/// </summary>
22-
[TestFixture(OwnerPersistence.DestroyWithOwner)]
23-
[TestFixture(OwnerPersistence.DontDestroyWithOwner)]
22+
[TestFixture(OwnerPersistence.DestroyWithOwner, HostOrServer.Host)]
23+
[TestFixture(OwnerPersistence.DontDestroyWithOwner, HostOrServer.Host)]
24+
#if UNIFIED_NETCODE
25+
[TestFixture(OwnerPersistence.DestroyWithOwner, HostOrServer.UnifiedHost)]
26+
[TestFixture(OwnerPersistence.DontDestroyWithOwner, HostOrServer.UnifiedHost)]
27+
#endif
2428
internal class DisconnectTests : NetcodeIntegrationTest
2529
{
2630
public enum OwnerPersistence
@@ -37,6 +41,13 @@ public enum ClientDisconnectType
3741

3842
protected override int NumberOfClients => 2;
3943

44+
#if UNIFIED_NETCODE
45+
protected override bool UseUnifiedTests()
46+
{
47+
return true;
48+
}
49+
#endif
50+
4051
private OwnerPersistence m_OwnerPersistence;
4152
private ClientDisconnectType m_ClientDisconnectType;
4253
private bool m_ClientDisconnected;
@@ -46,7 +57,7 @@ public enum ClientDisconnectType
4657
private ulong m_ClientId;
4758

4859

49-
public DisconnectTests(OwnerPersistence ownerPersistence) : base(HostOrServer.Host)
60+
public DisconnectTests(OwnerPersistence ownerPersistence, HostOrServer hostOrServer) : base(hostOrServer)
5061
{
5162
m_OwnerPersistence = ownerPersistence;
5263
}

‎com.unity.netcode.gameobjects/Tests/Runtime/PeerDisconnectCallbackTests.cs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ namespace Unity.Netcode.RuntimeTests
2222
/// </summary>
2323
[TestFixture(HostOrServer.Server)]
2424
[TestFixture(HostOrServer.Host)]
25+
#if UNIFIED_NETCODE
26+
[TestFixture(HostOrServer.UnifiedServer)]
27+
[TestFixture(HostOrServer.UnifiedHost)]
28+
#endif
2529
internal class PeerDisconnectCallbackTests : NetcodeIntegrationTest
2630
{
2731

@@ -33,6 +37,13 @@ public enum ClientDisconnectType
3337

3438
protected override int NumberOfClients => 3;
3539

40+
#if UNIFIED_NETCODE
41+
protected override bool UseUnifiedTests()
42+
{
43+
return true;
44+
}
45+
#endif
46+
3647
private int m_ClientDisconnectCount;
3748
private int m_PeerDisconnectCount;
3849

0 commit comments

Comments
 (0)