Skip to content

Commit 9fac991

Browse files
committed
Improve performance of NetworkSession.SendBundle
1 parent 7c90c0c commit 9fac991

File tree

2 files changed

+56
-35
lines changed

2 files changed

+56
-35
lines changed

Source/ACE.Server/Network/NetworkBundle.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ internal class NetworkBundle
99
private bool propChanged;
1010

1111
public bool NeedsSending => propChanged || messages.Count > 0;
12-
12+
public int MessageCount => messages.Count;
1313
public bool HasMoreMessages => messages.Count > 0;
1414

1515
private Queue<GameMessage> messages = new Queue<GameMessage>();

Source/ACE.Server/Network/NetworkSession.cs

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -809,39 +809,52 @@ private void SendBundle(NetworkBundle bundle, GameMessageGroup group)
809809
{
810810
packetLog.DebugFormat("[{0}] Sending Bundle", session.LoggingIdentifier);
811811

812-
bool writeOptionalHeaders = true;
813-
814-
List<MessageFragment> fragments = new List<MessageFragment>();
815-
816812
// Pull all messages out and create MessageFragment objects
817-
while (bundle.HasMoreMessages)
818-
{
819-
var message = bundle.Dequeue();
813+
var totalFragments = bundle.MessageCount;
814+
var fragments = new MessageFragment[totalFragments];
815+
for (int i = 0; i < totalFragments; i++)
816+
fragments[i] = new MessageFragment(bundle.Dequeue(), ConnectionData.FragmentSequence++);
820817

821-
var fragment = new MessageFragment(message, ConnectionData.FragmentSequence++);
822-
fragments.Add(fragment);
823-
}
818+
packetLog.DebugFormat("[{0}] Bundle Fragment Count: {1}", session.LoggingIdentifier, totalFragments);
824819

825-
packetLog.DebugFormat("[{0}] Bundle Fragment Count: {1}", session.LoggingIdentifier, fragments.Count);
820+
var hdrSize = PacketFragmentHeader.HeaderSize;
821+
int processedCount = 0;
822+
int lowerBoundIdx = 0;
823+
int seekIdx = 0;
824+
bool writeOptionalHeaders = true;
826825

827826
// Loop through while we have fragements
828-
while (fragments.Count > 0 || writeOptionalHeaders)
827+
while (processedCount < totalFragments || writeOptionalHeaders)
829828
{
829+
if (isReleased)
830+
return;
831+
830832
ServerPacket packet = new ServerPacket();
831833
PacketHeader packetHeader = packet.Header;
832834

833-
if (fragments.Count > 0)
835+
if (processedCount < totalFragments)
834836
packetHeader.Flags |= PacketHeaderFlags.BlobFragments;
835837

836838
if (bundle.EncryptedChecksum)
837839
packetHeader.Flags |= PacketHeaderFlags.EncryptedChecksum;
838840

839-
int availableSpace = ServerPacket.MaxPacketSize;
841+
seekIdx = lowerBoundIdx;
840842

841843
// Pull first message and see if it is a large one
842-
var firstMessage = fragments.FirstOrDefault();
844+
MessageFragment firstMessage = null;
845+
while (seekIdx < totalFragments)
846+
{
847+
firstMessage = fragments[seekIdx];
848+
if (firstMessage != null)
849+
break;
850+
seekIdx++;
851+
lowerBoundIdx++;
852+
}
853+
843854
if (firstMessage != null)
844855
{
856+
int availableSpace = ServerPacket.MaxPacketSize;
857+
845858
// If a large message send only this one, filling the whole packet
846859
if (firstMessage.DataRemaining >= availableSpace)
847860
{
@@ -850,7 +863,11 @@ private void SendBundle(NetworkBundle bundle, GameMessageGroup group)
850863
packet.Fragments.Add(spf);
851864
availableSpace -= spf.Length;
852865
if (firstMessage.DataRemaining <= 0)
853-
fragments.Remove(firstMessage);
866+
{
867+
processedCount++;
868+
lowerBoundIdx++;
869+
fragments[seekIdx++] = null;
870+
}
854871
}
855872
// Otherwise we'll write any optional headers and process any small messages that will fit
856873
else
@@ -863,23 +880,28 @@ private void SendBundle(NetworkBundle bundle, GameMessageGroup group)
863880
availableSpace -= (int)packet.Data.Length;
864881
}
865882

866-
// Create a list to remove completed messages after iterator
867-
List<MessageFragment> removeList = new List<MessageFragment>();
868-
869-
foreach (MessageFragment fragment in fragments)
883+
while (seekIdx < totalFragments)
870884
{
885+
var fragment = fragments[seekIdx];
886+
if (fragment == null)
887+
{
888+
seekIdx++;
889+
continue;
890+
}
891+
871892
bool fragmentSkipped = false;
872893

894+
873895
// Is this a large fragment and does it have a tail that needs sending?
874-
if (!fragment.TailSent && availableSpace >= fragment.TailSize)
896+
if (availableSpace >= hdrSize && !fragment.TailSent && availableSpace >= fragment.TailSize)
875897
{
876898
packetLog.DebugFormat("[{0}] Sending tail fragment", session.LoggingIdentifier);
877899
ServerPacketFragment spf = fragment.GetTailFragment();
878900
packet.Fragments.Add(spf);
879901
availableSpace -= spf.Length;
880902
}
881903
// Otherwise will this message fit in the remaining space?
882-
else if (availableSpace >= fragment.NextSize)
904+
else if (availableSpace >= hdrSize && availableSpace >= fragment.NextSize)
883905
{
884906
packetLog.DebugFormat("[{0}] Sending small message", session.LoggingIdentifier);
885907
ServerPacketFragment spf = fragment.GetNextFragment();
@@ -891,28 +913,27 @@ private void SendBundle(NetworkBundle bundle, GameMessageGroup group)
891913

892914
// If message is out of data, set to remove it
893915
if (fragment.DataRemaining <= 0)
894-
removeList.Add(fragment);
916+
{
917+
processedCount++;
918+
if (seekIdx == lowerBoundIdx)
919+
lowerBoundIdx++;
920+
fragments[seekIdx] = null;
921+
}
895922

896923
// UIQueue messages must go out in order. Otherwise, you might see an NPC's tells in an order that doesn't match their defined emotes.
897924
if (fragmentSkipped && group == GameMessageGroup.UIQueue)
898925
break;
899-
}
900926

901-
// Remove all completed messages
902-
fragments.RemoveAll(x => removeList.Contains(x));
927+
seekIdx++;
928+
}
903929
}
904930
}
905931
// If no messages, write optional headers
906-
else
932+
else if (writeOptionalHeaders)
907933
{
908934
packetLog.DebugFormat("[{0}] No messages, just sending optional headers", session.LoggingIdentifier);
909-
if (writeOptionalHeaders)
910-
{
911-
writeOptionalHeaders = false;
912-
WriteOptionalHeaders(bundle, packet);
913-
if (packet.Data != null)
914-
availableSpace -= (int)packet.Data.Length;
915-
}
935+
writeOptionalHeaders = false;
936+
WriteOptionalHeaders(bundle, packet);
916937
}
917938
EnqueueSend(packet);
918939
}

0 commit comments

Comments
 (0)