@@ -58,6 +58,8 @@ public SendQueueItem(NetworkDelivery delivery, int writerSize, Allocator writerA
58
58
private Dictionary < Type , uint > m_MessageTypes = new Dictionary < Type , uint > ( ) ;
59
59
private Dictionary < ulong , NativeList < SendQueueItem > > m_SendQueues = new Dictionary < ulong , NativeList < SendQueueItem > > ( ) ;
60
60
61
+ private HashSet < ulong > m_DisconnectedClients = new HashSet < ulong > ( ) ;
62
+
61
63
// This is m_PerClientMessageVersion[clientId][messageType] = version
62
64
private Dictionary < ulong , Dictionary < Type , int > > m_PerClientMessageVersions = new Dictionary < ulong , Dictionary < Type , int > > ( ) ;
63
65
private Dictionary < uint , Type > m_MessagesByHash = new Dictionary < uint , Type > ( ) ;
@@ -155,8 +157,9 @@ public unsafe void Dispose()
155
157
// from the queue.
156
158
foreach ( var kvp in m_SendQueues )
157
159
{
158
- CleanupDisconnectedClient ( kvp . Key ) ;
160
+ ClientDisconnected ( kvp . Key ) ;
159
161
}
162
+ CleanupDisconnectedClients ( ) ;
160
163
161
164
for ( var queueIndex = 0 ; queueIndex < m_IncomingMessageQueue . Length ; ++ queueIndex )
162
165
{
@@ -464,41 +467,37 @@ internal void ClientConnected(ulong clientId)
464
467
}
465
468
466
469
internal void ClientDisconnected ( ulong clientId )
470
+ {
471
+ m_DisconnectedClients . Add ( clientId ) ;
472
+ }
473
+
474
+ private void CleanupDisconnectedClient ( ulong clientId )
467
475
{
468
476
if ( ! m_SendQueues . ContainsKey ( clientId ) )
469
477
{
470
478
return ;
471
479
}
472
- CleanupDisconnectedClient ( clientId ) ;
473
- m_SendQueues . Remove ( clientId ) ;
474
- }
475
480
476
- private void CleanupDisconnectedClient ( ulong clientId )
477
- {
478
481
var queue = m_SendQueues [ clientId ] ;
479
482
for ( var i = 0 ; i < queue . Length ; ++ i )
480
483
{
481
484
queue . ElementAt ( i ) . Writer . Dispose ( ) ;
482
485
}
483
486
484
487
queue . Dispose ( ) ;
488
+ m_SendQueues . Remove ( clientId ) ;
489
+
490
+ m_PerClientMessageVersions . Remove ( clientId ) ;
485
491
}
486
492
487
493
internal void CleanupDisconnectedClients ( )
488
494
{
489
- var removeList = new NativeList < ulong > ( Allocator . Temp ) ;
490
- foreach ( var clientId in m_PerClientMessageVersions . Keys )
495
+ foreach ( var clientId in m_DisconnectedClients )
491
496
{
492
- if ( ! m_SendQueues . ContainsKey ( clientId ) )
493
- {
494
- removeList . Add ( clientId ) ;
495
- }
497
+ CleanupDisconnectedClient ( clientId ) ;
496
498
}
497
499
498
- foreach ( var clientId in removeList )
499
- {
500
- m_PerClientMessageVersions . Remove ( clientId ) ;
501
- }
500
+ m_DisconnectedClients . Clear ( ) ;
502
501
}
503
502
504
503
public static int CreateMessageAndGetVersion < T > ( ) where T : INetworkMessage , new ( )
@@ -637,6 +636,10 @@ internal unsafe int SendPreSerializedMessage<TMessageType>(in FastBufferWriter t
637
636
638
637
for ( var i = 0 ; i < clientIds . Count ; ++ i )
639
638
{
639
+ if ( m_DisconnectedClients . Contains ( clientIds [ i ] ) )
640
+ {
641
+ continue ;
642
+ }
640
643
var messageVersion = 0 ;
641
644
// Special case because this is the message that carries the version info - thus the version info isn't
642
645
// populated yet when we get this. The first part of this message always has to be the version data
@@ -788,6 +791,14 @@ internal unsafe void ProcessSendQueues()
788
791
for ( var i = 0 ; i < sendQueueItem . Length ; ++ i )
789
792
{
790
793
ref var queueItem = ref sendQueueItem . ElementAt ( i ) ;
794
+ // this is checked at every iteration because
795
+ // 1) each writer needs to be disposed, so we have to do the full loop regardless, and
796
+ // 2) the call to m_MessageSender.Send() may result in calling ClientDisconnected(), so the result of this check may change partway through iteration
797
+ if ( m_DisconnectedClients . Contains ( clientId ) )
798
+ {
799
+ queueItem . Writer . Dispose ( ) ;
800
+ continue ;
801
+ }
791
802
if ( queueItem . BatchHeader . BatchCount == 0 )
792
803
{
793
804
queueItem . Writer . Dispose ( ) ;
0 commit comments