3 Commits

5 changed files with 65 additions and 9 deletions

View File

@@ -8,6 +8,19 @@ public class DummyClientService
private readonly List<DummyClients> clients; private readonly List<DummyClients> clients;
private readonly int sendInterval; private readonly int sendInterval;
// 유닛 테스트용 (n패킷 시간체크)
public bool IsTest
{
get;
set;
} = false;
public int TestCount
{
get;
set;
} = 100000;
// 모든거 강종 // 모든거 강종
public event Action? OnAllDisconnected; public event Action? OnAllDisconnected;
@@ -21,6 +34,16 @@ public class DummyClientService
public async Task RunAsync(CancellationToken ct) public async Task RunAsync(CancellationToken ct)
{ {
if (IsTest)
{
foreach (DummyClients c in clients)
{
c.TestCount = TestCount;
}
Log.Information("[TEST] 유닛 테스트 모드: 클라이언트당 {Count}개 수신 시 자동 종료", TestCount);
}
await Task.WhenAll( await Task.WhenAll(
PollLoopAsync(ct), PollLoopAsync(ct),
SendLoopAsync(ct) SendLoopAsync(ct)
@@ -103,6 +126,7 @@ public class DummyClientService
{ {
int totalSent = 0, totalRecv = 0; int totalSent = 0, totalRecv = 0;
int connected = 0; int connected = 0;
int rttClientCount = 0;
Log.Information("───────────── Performance Report ─────────────"); Log.Information("───────────── Performance Report ─────────────");
@@ -120,14 +144,18 @@ public class DummyClientService
totalSent += c.SentCount; totalSent += c.SentCount;
totalRecv += c.ReceivedCount; totalRecv += c.ReceivedCount;
totalAvgRtt += c.AvgRttMs; if (c.RttCount > 0)
{
totalAvgRtt += c.AvgRttMs;
rttClientCount++;
}
if (c.peer != null) if (c.peer != null)
{ {
connected++; connected++;
} }
} }
double avgRtt = connected > 0 ? totalAvgRtt / connected : 0; double avgRtt = rttClientCount > 0 ? totalAvgRtt / rttClientCount : 0;
Log.Information("────────────────────────────────────────────"); Log.Information("────────────────────────────────────────────");
Log.Information( Log.Information(

View File

@@ -20,6 +20,13 @@ public class DummyClients
private int seqNumber; private int seqNumber;
private const int MaxPendingPings = 1000; private const int MaxPendingPings = 1000;
// 유닛 테스트용 (0 = 제한 없음)
public int TestCount
{
get;
set;
} = 0;
// 통계 // 통계
public int SentCount public int SentCount
{ {
@@ -82,6 +89,12 @@ public class DummyClients
} }
ReceivedCount++; ReceivedCount++;
if (TestCount > 0 && ReceivedCount >= TestCount)
{
peer.Disconnect();
}
reader.Recycle(); reader.Recycle();
}; };

View File

@@ -35,6 +35,8 @@ class EcoClientTester
cts.Cancel(); cts.Cancel();
}; };
// service.IsTest = true;
// service.TestCount = 100;
await service.RunAsync(cts.Token); await service.RunAsync(cts.Token);
service.PrintStats(); service.PrintStats();

View File

@@ -36,11 +36,25 @@ public abstract class ServerBase : INetEventListener
// peer → hashKey 역방향은 peer.Tag as Session 으로 대체 // peer → hashKey 역방향은 peer.Tag as Session 으로 대체
private readonly Dictionary<long, NetPeer> sessions = new(); private readonly Dictionary<long, NetPeer> sessions = new();
// 핑 로그 출력 여부 // 재사용 NetDataWriter (단일 스레드 폴링이므로 안전)
public bool PingLogRtt { get; set; } private readonly NetDataWriter cachedWriter = new();
public int Port { get; } // 핑 로그 출력 여부
public string ConnectionString { get; } public bool PingLogRtt
{
get;
set;
}
public int Port
{
get;
}
public string ConnectionString
{
get;
}
private volatile bool isListening = false; private volatile bool isListening = false;
@@ -71,6 +85,7 @@ public abstract class ServerBase : INetEventListener
netManager.PollEvents(); netManager.PollEvents();
await Task.Delay(1); await Task.Delay(1);
} }
netManager.Stop(); netManager.Stop();
Log.Information("[Server] 종료 Port={Port}", Port); Log.Information("[Server] 종료 Port={Port}", Port);
} }
@@ -112,6 +127,7 @@ public abstract class ServerBase : INetEventListener
Log.Information("[Server] 세션 해제 HashKey={Key} Reason={Reason}", session.HashKey, disconnectInfo.Reason); Log.Information("[Server] 세션 해제 HashKey={Key} Reason={Reason}", session.HashKey, disconnectInfo.Reason);
OnSessionDisconnected(peer, session.HashKey, disconnectInfo); OnSessionDisconnected(peer, session.HashKey, disconnectInfo);
} }
peer.Tag = null; peer.Tag = null;
} }
} }
@@ -235,9 +251,6 @@ public abstract class ServerBase : INetEventListener
// ─── 전송 헬퍼 ─────────────────────────────────────────────────────── // ─── 전송 헬퍼 ───────────────────────────────────────────────────────
// 재사용 NetDataWriter (단일 스레드 폴링이므로 안전)
private readonly NetDataWriter cachedWriter = new();
// peer에게 전송 // peer에게 전송
protected void SendTo(NetPeer peer, byte[] data, DeliveryMethod method = DeliveryMethod.ReliableOrdered) protected void SendTo(NetPeer peer, byte[] data, DeliveryMethod method = DeliveryMethod.ReliableOrdered)
{ {