diff --git a/ClientTester/EchoClientTester/DummyService/DummyClientService.cs b/ClientTester/EchoClientTester/DummyService/DummyClientService.cs index 0c40ac8..400938f 100644 --- a/ClientTester/EchoClientTester/DummyService/DummyClientService.cs +++ b/ClientTester/EchoClientTester/DummyService/DummyClientService.cs @@ -100,12 +100,9 @@ public class DummyClientService { int totalSent = 0, totalRecv = 0; int connected = 0; - int rttClientCount = 0; Log.Information("───────────── Performance Report ─────────────"); - double totalAvgRtt = 0; - foreach (DummyClients c in clients) { NetStatistics? stats = c.peer?.Statistics; @@ -113,16 +110,11 @@ public class DummyClientService float lossPct = stats?.PacketLossPercent ?? 0f; Log.Information( - "[Client {ClientId:00}] Sent={Sent} Recv={Recv} | Loss={Loss}({LossPct:F1}%) AvgRTT={AvgRtt:F3}ms LastRTT={LastRtt:F3}ms", - c.clientId, c.SentCount, c.ReceivedCount, loss, lossPct, c.AvgRttMs, c.LastRttMs); + "[Client {ClientId:00}] Sent={Sent} Recv={Recv} | Loss={Loss}({LossPct:F1}%)", + c.clientId, c.SentCount, c.ReceivedCount, loss, lossPct); totalSent += c.SentCount; totalRecv += c.ReceivedCount; - if (c.RttCount > 0) - { - totalAvgRtt += c.AvgRttMs; - rttClientCount++; - } if (c.peer != null) { @@ -130,12 +122,10 @@ public class DummyClientService } } - double avgRtt = rttClientCount > 0 ? totalAvgRtt / rttClientCount : 0; - Log.Information("────────────────────────────────────────────"); Log.Information( - "[TOTAL] Sent={Sent} Recv={Recv} Connected={Connected}/{Total} AvgRTT={AvgRtt:F3}ms", - totalSent, totalRecv, connected, clients.Count, avgRtt); + "[TOTAL] Sent={Sent} Recv={Recv} Connected={Connected}/{Total}", + totalSent, totalRecv, connected, clients.Count); Log.Information("────────────────────────────────────────────"); } diff --git a/ClientTester/EchoClientTester/DummyService/DummyClients.cs b/ClientTester/EchoClientTester/DummyService/DummyClients.cs index 1a4adeb..ff01e3e 100644 --- a/ClientTester/EchoClientTester/DummyService/DummyClients.cs +++ b/ClientTester/EchoClientTester/DummyService/DummyClients.cs @@ -1,4 +1,3 @@ -using System.Collections.Concurrent; using System.Diagnostics; using ClientTester.Packet; using LiteNetLib; @@ -13,12 +12,7 @@ public class DummyClients private EventBasedNetListener listener; private NetDataWriter? writer; public NetPeer? peer; - public long clientId; - - // seq → 송신 타임스탬프 (Stopwatch tick) - private ConcurrentDictionary pendingPings = new(); - private int seqNumber; - private const int MAX_PENDING_PINGS = 1000; + public long clientId; // 일단 이게 hashKey가 됨 => 0 ~ 1000번까지는 더미용응로 뺴둠 // info private Vector3 position = new Vector3(); @@ -28,20 +22,12 @@ public class DummyClients private float preTime = 0.0f; // 이동 계산용 - private static readonly Random random = new(); private readonly Stopwatch moveClock = Stopwatch.StartNew(); private float posX = 0f; private float posZ = 0f; private float dirX = 0f; private float dirZ = 0f; - // 유닛 테스트용 (0 = 제한 없음) - public int TestCount - { - get; - set; - } = 0; - // 통계 public int SentCount { @@ -55,18 +41,6 @@ public class DummyClients get; } - public double LastRttMs - { - set; - get; - } - - public double TotalRttMs - { - set; - get; - } - public int RttCount { set; @@ -86,11 +60,13 @@ public class DummyClients Log.Information("[Client {ClientId:00}] 연결됨", this.clientId); // clientID가 토큰의 hashKey라고 가정함 - PacketHeader packetHeader = new PacketHeader(); - packetHeader.Code = (PacketCode)1; - packetHeader.BodyLength = 4 + sizeof(long); - writer.Put(clientId); + AccTokenPacket recvTokenPacket = new AccTokenPacket(); + recvTokenPacket.Token = clientId; + + byte[] data = PacketSerializer.Serialize((ushort)PacketCode.ACC_TOKEN, recvTokenPacket); + writer.Put(data); peer.Send(writer, DeliveryMethod.ReliableOrdered); + writer.Reset(); }; listener.NetworkReceiveEvent += (peer, reader, channel, deliveryMethod) => @@ -98,25 +74,13 @@ public class DummyClients short code = reader.GetShort(); short bodyLength = reader.GetShort(); string? msg = reader.GetString(); - long sentTick; - if (msg != null && msg.StartsWith("Echo seq:") && - int.TryParse(msg.Substring("Echo seq:".Length), out int seq) && - pendingPings.TryRemove(seq, out sentTick)) + if (msg != null) { - double rttMs = (Stopwatch.GetTimestamp() - sentTick) * 1000.0 / Stopwatch.Frequency; - LastRttMs = rttMs; - TotalRttMs += rttMs; RttCount++; } ReceivedCount++; - - if (TestCount > 0 && ReceivedCount >= TestCount) - { - peer.Disconnect(); - } - reader.Recycle(); }; @@ -141,13 +105,13 @@ public class DummyClients if (distance <= 0f) { // 현재 각도에서 -30~+30도 범위로 회전 - rotY = (rotY + random.Next(-30, 31) + 360) % 360; + rotY = (rotY + Random.Shared.Next(-30, 31) + 360) % 360; float rad = rotY * MathF.PI / 180f; dirX = MathF.Sin(rad); dirZ = MathF.Cos(rad); // 3초~12초에 도달할 수 있는 거리 = moveSpeed × 랜덤 초 - float seconds = 3f + (float)random.NextDouble() * 9f; + float seconds = 3f + (float)Random.Shared.NextDouble() * 9f; distance = moveSpeed * seconds; } @@ -170,10 +134,6 @@ public class DummyClients } UpdateDummy(); - - int seq = seqNumber++; - pendingPings[seq] = Stopwatch.GetTimestamp(); - TransformPlayerPacket transformPlayerPacket = new TransformPlayerPacket { PlayerId = (int)clientId, @@ -195,8 +155,6 @@ public class DummyClients writer.Reset(); } - public double AvgRttMs => RttCount > 0 ? TotalRttMs / RttCount : 0.0; - public void PollEvents() { manager.PollEvents(); diff --git a/ClientTester/EchoClientTester/EchoDummyService/EchoDummyClients.cs b/ClientTester/EchoClientTester/EchoDummyService/EchoDummyClients.cs index 95caa4b..e809ef8 100644 --- a/ClientTester/EchoClientTester/EchoDummyService/EchoDummyClients.cs +++ b/ClientTester/EchoClientTester/EchoDummyService/EchoDummyClients.cs @@ -18,7 +18,7 @@ public class EchoDummyClients // seq → 송신 타임스탬프 (Stopwatch tick) private ConcurrentDictionary pendingPings = new(); private int seqNumber; - private const int MaxPendingPings = 1000; + private const int MAX_PENDING_PINGS = 1000; // 유닛 테스트용 (0 = 제한 없음) public int TestCount @@ -119,13 +119,15 @@ public class EchoDummyClients pendingPings[seq] = Stopwatch.GetTimestamp(); // 응답 없는 오래된 ping 정리 (패킷 유실 시 메모리 누수 방지) - if (pendingPings.Count > MaxPendingPings) + if (pendingPings.Count > MAX_PENDING_PINGS) { - int cutoff = seq - MaxPendingPings; + int cutoff = seq - MAX_PENDING_PINGS; foreach (int key in pendingPings.Keys) { if (key < cutoff) + { pendingPings.TryRemove(key, out _); + } } } diff --git a/ClientTester/EchoClientTester/Packet/PacketBody.cs b/ClientTester/EchoClientTester/Packet/PacketBody.cs index 677c00f..aed4292 100644 --- a/ClientTester/EchoClientTester/Packet/PacketBody.cs +++ b/ClientTester/EchoClientTester/Packet/PacketBody.cs @@ -104,12 +104,12 @@ public class PlayerInfo // 인증 // ============================================================ -// RECV_TOKEN +// ACC_TOKEN [ProtoContract] -public class RecvTokenPacket +public class AccTokenPacket { [ProtoMember(1)] - public string Token + public long Token { get; set; diff --git a/ClientTester/EchoClientTester/Packet/PacketHeader.cs b/ClientTester/EchoClientTester/Packet/PacketHeader.cs index fbe6ee6..ee28321 100644 --- a/ClientTester/EchoClientTester/Packet/PacketHeader.cs +++ b/ClientTester/EchoClientTester/Packet/PacketHeader.cs @@ -3,7 +3,7 @@ namespace ClientTester.Packet; public enum PacketCode : ushort { // 초기 클라이언트 시작시 jwt토큰 받아옴 - RECV_TOKEN, + ACC_TOKEN = 1, // 내 정보 로드 (서버 -> 클라) LOAD_GAME,