diff --git a/LiteNetLib/NetManager.Socket.cs b/LiteNetLib/NetManager.Socket.cs index 67b07f33..61f5024d 100644 --- a/LiteNetLib/NetManager.Socket.cs +++ b/LiteNetLib/NetManager.Socket.cs @@ -608,7 +608,7 @@ internal int SendRaw(byte[] message, int start, int length, IPEndPoint remoteEnd if (EnableStatistics) { - Statistics.IncrementPacketsSent(); + Statistics.IncrementPacketsSent(1); Statistics.AddBytesSent(length); } diff --git a/LiteNetLib/NetPeer.cs b/LiteNetLib/NetPeer.cs index 1852e69c..5cd95639 100644 --- a/LiteNetLib/NetPeer.cs +++ b/LiteNetLib/NetPeer.cs @@ -1268,7 +1268,7 @@ private void SendMerged() if (NetManager.EnableStatistics) { - Statistics.IncrementPacketsSent(); + Statistics.IncrementPacketsSent(_mergeCount); Statistics.AddBytesSent(bytesSent); } @@ -1288,7 +1288,7 @@ internal void SendUserData(NetPacket packet) if (NetManager.EnableStatistics) { - Statistics.IncrementPacketsSent(); + Statistics.IncrementPacketsSent(1); Statistics.AddBytesSent(bytesSent); } diff --git a/LiteNetLib/NetStatistics.cs b/LiteNetLib/NetStatistics.cs index 032e2754..17402205 100644 --- a/LiteNetLib/NetStatistics.cs +++ b/LiteNetLib/NetStatistics.cs @@ -1,20 +1,34 @@ -using System.Threading; +using System; +using System.Collections.Concurrent; +using System.Linq; +using System.Threading; namespace LiteNetLib { public sealed class NetStatistics { + public bool TrackAveragePacketSize; + public int PacketSizeAverageWindow = 256; + + public bool TrackAveragePacketMergeCount; + public int PacketMergeAverageWindow = 256; + private long _packetsSent; private long _packetsReceived; private long _bytesSent; private long _bytesReceived; private long _packetLoss; + private long _windowWaits; + + ConcurrentQueue _packetSizes = new ConcurrentQueue(); + ConcurrentQueue _packetMerges = new ConcurrentQueue(); public long PacketsSent => Interlocked.Read(ref _packetsSent); public long PacketsReceived => Interlocked.Read(ref _packetsReceived); public long BytesSent => Interlocked.Read(ref _bytesSent); public long BytesReceived => Interlocked.Read(ref _bytesReceived); public long PacketLoss => Interlocked.Read(ref _packetLoss); + public long WindowWaitCount => Interlocked.Read(ref _windowWaits); public long PacketLossPercent { @@ -26,6 +40,47 @@ public long PacketLossPercent } } + public double ComputeAveragePacketSize() + { + if (!TrackAveragePacketSize) + throw new InvalidOperationException("Tracking average packet size is not enabled"); + + return ComputeAverage(_packetSizes, size => (double)size); + } + + public double ComputeAveragePacketMerge() + { + if (!TrackAveragePacketMergeCount) + throw new InvalidOperationException("Tracking average packet merge is not enabled"); + + return ComputeAverage(_packetMerges, count => (double)count); + } + + double ComputeAverage(ConcurrentQueue data, Func selector) + { + int count = 0; + double sum = 0; + + foreach (var value in data) + { + count++; + sum += selector(value); + } + + if (count == 0) + return 0; + + return sum / count; + } + + void Store(ConcurrentQueue data, T value, int max) + { + data.Enqueue(value); + + while (data.Count > 0 && data.Count > max) + data.TryDequeue(out _); + } + public void Reset() { Interlocked.Exchange(ref _packetsSent, 0); @@ -33,11 +88,20 @@ public void Reset() Interlocked.Exchange(ref _bytesSent, 0); Interlocked.Exchange(ref _bytesReceived, 0); Interlocked.Exchange(ref _packetLoss, 0); + Interlocked.Exchange(ref _windowWaits, 0); + +#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER + _packetSizes.Clear(); + _packetMerges.Clear(); +#endif } - public void IncrementPacketsSent() + public void IncrementPacketsSent(int merged) { Interlocked.Increment(ref _packetsSent); + + if (TrackAveragePacketMergeCount) + Store(_packetMerges, merged, PacketMergeAverageWindow); } public void IncrementPacketsReceived() @@ -48,6 +112,9 @@ public void IncrementPacketsReceived() public void AddBytesSent(long bytesSent) { Interlocked.Add(ref _bytesSent, bytesSent); + + if (TrackAveragePacketSize) + Store(_packetSizes, bytesSent, PacketSizeAverageWindow); } public void AddBytesReceived(long bytesReceived) @@ -65,17 +132,23 @@ public void AddPacketLoss(long packetLoss) Interlocked.Add(ref _packetLoss, packetLoss); } + public void IncrementWindowWaits() + { + Interlocked.Increment(ref _windowWaits); + } + public override string ToString() { return string.Format( - "BytesReceived: {0}\nPacketsReceived: {1}\nBytesSent: {2}\nPacketsSent: {3}\nPacketLoss: {4}\nPacketLossPercent: {5}\n", + "BytesReceived: {0}\nPacketsReceived: {1}\nBytesSent: {2}\nPacketsSent: {3}\nPacketLoss: {4}\nPacketLossPercent: {5}\nWindow Wait Count: {6}", BytesReceived, PacketsReceived, BytesSent, PacketsSent, PacketLoss, - PacketLossPercent); + PacketLossPercent, + WindowWaitCount); } } } diff --git a/LiteNetLib/ReliableChannel.cs b/LiteNetLib/ReliableChannel.cs index 4a10d170..fabc0fd2 100644 --- a/LiteNetLib/ReliableChannel.cs +++ b/LiteNetLib/ReliableChannel.cs @@ -187,7 +187,12 @@ protected override bool SendNextPackets() { int relate = NetUtils.RelativeSequenceNumber(_localSeqence, _localWindowStart); if (relate >= _windowSize) + { + if (Peer.NetManager.EnableStatistics) + Peer.Statistics.IncrementWindowWaits(); + break; + } var netPacket = OutgoingQueue.Dequeue(); netPacket.Sequence = (ushort) _localSeqence; @@ -294,7 +299,7 @@ public override bool ProcessPacket(NetPacket packet) //detailed check if (seq == _remoteSequence) { - NetDebug.Write("[RR]ReliableInOrder packet succes"); + NetDebug.Write("[RR]ReliableInOrder packet success"); Peer.AddReliablePacket(_deliveryMethod, packet); _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence;