@@ -23,7 +23,7 @@ void CreateDriver(
23
23
out NetworkDriver driver ,
24
24
out NetworkPipeline unreliableFragmentedPipeline ,
25
25
out NetworkPipeline unreliableSequencedFragmentedPipeline ,
26
- out NetworkPipeline reliableSequencedFragmentedPipeline ) ;
26
+ out NetworkPipeline reliableSequencedPipeline ) ;
27
27
}
28
28
29
29
public static class ErrorUtilities
@@ -160,7 +160,7 @@ public static implicit operator ConnectionAddressData(NetworkEndPoint d) =>
160
160
161
161
private NetworkPipeline m_UnreliableFragmentedPipeline ;
162
162
private NetworkPipeline m_UnreliableSequencedFragmentedPipeline ;
163
- private NetworkPipeline m_ReliableSequencedFragmentedPipeline ;
163
+ private NetworkPipeline m_ReliableSequencedPipeline ;
164
164
165
165
public override ulong ServerClientId => m_ServerClientId ;
166
166
@@ -210,14 +210,19 @@ public SimulatorUtility.Parameters ClientSimulatorParameters
210
210
/// </summary>
211
211
private readonly Dictionary < SendTarget , BatchedSendQueue > m_SendQueue = new Dictionary < SendTarget , BatchedSendQueue > ( ) ;
212
212
213
+ // Since reliable messages may be spread out over multiple transport payloads, it's possible
214
+ // to receive only parts of a message in an update. We thus keep the reliable receive queues
215
+ // around to avoid losing partial messages.
216
+ private readonly Dictionary < ulong , BatchedReceiveQueue > m_ReliableReceiveQueues = new Dictionary < ulong , BatchedReceiveQueue > ( ) ;
217
+
213
218
private void InitDriver ( )
214
219
{
215
220
DriverConstructor . CreateDriver (
216
221
this ,
217
222
out m_Driver ,
218
223
out m_UnreliableFragmentedPipeline ,
219
224
out m_UnreliableSequencedFragmentedPipeline ,
220
- out m_ReliableSequencedFragmentedPipeline ) ;
225
+ out m_ReliableSequencedPipeline ) ;
221
226
}
222
227
223
228
private void DisposeDriver ( )
@@ -241,7 +246,7 @@ private NetworkPipeline SelectSendPipeline(NetworkDelivery delivery)
241
246
case NetworkDelivery . Reliable :
242
247
case NetworkDelivery . ReliableSequenced :
243
248
case NetworkDelivery . ReliableFragmentedSequenced :
244
- return m_ReliableSequencedFragmentedPipeline ;
249
+ return m_ReliableSequencedPipeline ;
245
250
246
251
default :
247
252
Debug . LogError ( $ "Unknown { nameof ( NetworkDelivery ) } value: { delivery } ") ;
@@ -340,6 +345,11 @@ private static RelayConnectionData ConvertConnectionData(byte[] connectionData)
340
345
}
341
346
}
342
347
348
+ internal void SetMaxPayloadSize ( int maxPayloadSize )
349
+ {
350
+ m_MaxPayloadSize = maxPayloadSize ;
351
+ }
352
+
343
353
private void SetProtocol ( ProtocolType inProtocol )
344
354
{
345
355
m_ProtocolType = inProtocol ;
@@ -439,7 +449,14 @@ private void SendBatchedMessages(SendTarget sendTarget, BatchedSendQueue queue)
439
449
return ;
440
450
}
441
451
442
- var written = queue . FillWriter ( ref writer ) ;
452
+ // We don't attempt to send entire payloads over the reliable pipeline. Instead we
453
+ // fragment it manually. This is safe and easy to do since the reliable pipeline
454
+ // basically implements a stream, so as long as we separate the different messages
455
+ // in the stream (the send queue does that automatically) we are sure they'll be
456
+ // reassembled properly at the other end. This allows us to lift the limit of ~44KB
457
+ // on reliable payloads (because of the reliable window size).
458
+ var written = pipeline == m_ReliableSequencedPipeline
459
+ ? queue . FillWriterWithBytes ( ref writer ) : queue . FillWriterWithMessages ( ref writer ) ;
443
460
444
461
result = m_Driver . EndSend ( writer ) ;
445
462
if ( result == written )
@@ -481,9 +498,42 @@ private bool AcceptConnection()
481
498
482
499
}
483
500
501
+ private void ReceiveMessages ( ulong clientId , NetworkPipeline pipeline , DataStreamReader dataReader )
502
+ {
503
+ BatchedReceiveQueue queue ;
504
+ if ( pipeline == m_ReliableSequencedPipeline )
505
+ {
506
+ if ( m_ReliableReceiveQueues . TryGetValue ( clientId , out queue ) )
507
+ {
508
+ queue . PushReader ( dataReader ) ;
509
+ }
510
+ else
511
+ {
512
+ queue = new BatchedReceiveQueue ( dataReader ) ;
513
+ m_ReliableReceiveQueues [ clientId ] = queue ;
514
+ }
515
+ }
516
+ else
517
+ {
518
+ queue = new BatchedReceiveQueue ( dataReader ) ;
519
+ }
520
+
521
+ while ( ! queue . IsEmpty )
522
+ {
523
+ var message = queue . PopMessage ( ) ;
524
+ if ( message == default )
525
+ {
526
+ // Only happens if there's only a partial message in the queue (rare).
527
+ break ;
528
+ }
529
+
530
+ InvokeOnTransportEvent ( NetcodeNetworkEvent . Data , clientId , message , Time . realtimeSinceStartup ) ;
531
+ }
532
+ }
533
+
484
534
private bool ProcessEvent ( )
485
535
{
486
- var eventType = m_Driver . PopEvent ( out var networkConnection , out var reader ) ;
536
+ var eventType = m_Driver . PopEvent ( out var networkConnection , out var reader , out var pipeline ) ;
487
537
488
538
switch ( eventType )
489
539
{
@@ -510,6 +560,8 @@ private bool ProcessEvent()
510
560
}
511
561
}
512
562
563
+ m_ReliableReceiveQueues . Remove ( ParseClientId ( networkConnection ) ) ;
564
+
513
565
InvokeOnTransportEvent ( NetcodeNetworkEvent . Disconnect ,
514
566
ParseClientId ( networkConnection ) ,
515
567
default ( ArraySegment < byte > ) ,
@@ -520,17 +572,7 @@ private bool ProcessEvent()
520
572
}
521
573
case TransportNetworkEvent . Type . Data :
522
574
{
523
- var queue = new BatchedReceiveQueue ( reader ) ;
524
-
525
- while ( ! queue . IsEmpty )
526
- {
527
- InvokeOnTransportEvent ( NetcodeNetworkEvent . Data ,
528
- ParseClientId ( networkConnection ) ,
529
- queue . PopMessage ( ) ,
530
- Time . realtimeSinceStartup
531
- ) ;
532
- }
533
-
575
+ ReceiveMessages ( ParseClientId ( networkConnection ) , pipeline , reader ) ;
534
576
return true ;
535
577
}
536
578
}
@@ -744,7 +786,7 @@ public override void Shutdown()
744
786
public void CreateDriver ( UnityTransport transport , out NetworkDriver driver ,
745
787
out NetworkPipeline unreliableFragmentedPipeline ,
746
788
out NetworkPipeline unreliableSequencedFragmentedPipeline ,
747
- out NetworkPipeline reliableSequencedFragmentedPipeline )
789
+ out NetworkPipeline reliableSequencedPipeline )
748
790
{
749
791
var maxFrameTimeMS = 0 ;
750
792
@@ -775,8 +817,7 @@ public void CreateDriver(UnityTransport transport, out NetworkDriver driver,
775
817
typeof ( UnreliableSequencedPipelineStage ) ,
776
818
typeof ( SimulatorPipelineStage ) ,
777
819
typeof ( SimulatorPipelineStageInSend ) ) ;
778
- reliableSequencedFragmentedPipeline = driver . CreatePipeline (
779
- typeof ( FragmentationPipelineStage ) ,
820
+ reliableSequencedPipeline = driver . CreatePipeline (
780
821
typeof ( ReliableSequencedPipelineStage ) ,
781
822
typeof ( SimulatorPipelineStage ) ,
782
823
typeof ( SimulatorPipelineStageInSend ) ) ;
@@ -788,8 +829,8 @@ public void CreateDriver(UnityTransport transport, out NetworkDriver driver,
788
829
typeof ( FragmentationPipelineStage ) ) ;
789
830
unreliableSequencedFragmentedPipeline = driver . CreatePipeline (
790
831
typeof ( FragmentationPipelineStage ) , typeof ( UnreliableSequencedPipelineStage ) ) ;
791
- reliableSequencedFragmentedPipeline = driver . CreatePipeline (
792
- typeof ( FragmentationPipelineStage ) , typeof ( ReliableSequencedPipelineStage )
832
+ reliableSequencedPipeline = driver . CreatePipeline (
833
+ typeof ( ReliableSequencedPipelineStage )
793
834
) ;
794
835
}
795
836
}
0 commit comments