feat : 스트레스 테스트 기능 추가 / 패킷 처리량 제한 / 프로젝트 상황 리드미 추가

This commit is contained in:
qornwh1
2026-03-05 10:58:49 +09:00
parent 2be1302b24
commit ea3f64a40d
11 changed files with 1668 additions and 31 deletions

View File

@@ -184,6 +184,22 @@ public abstract class ServerBase : INetEventListener
return;
}
// 패킷 레이트 리미팅 체크
if (session.CheckRateLimit())
{
// 3회 연속 초과 시 강제 연결 해제
if (session.RateLimitViolations >= 3)
{
Log.Warning("[Server] 레이트 리밋 초과 강제 해제 HashKey={Key} PeerId={Id}", session.HashKey, peer.Id);
peer.Disconnect();
return;
}
Log.Warning("[Server] 레이트 리밋 초과 ({Count}회) HashKey={Key} PeerId={Id}", session.RateLimitViolations, session.HashKey,
peer.Id);
return; // 패킷 드롭
}
HandlePacket(peer, session.HashKey, type, payload);
}
catch (Exception ex)

View File

@@ -22,10 +22,55 @@ public class Session
set;
}
public Session(long hashKey, NetPeer peer)
// ─── 패킷 레이트 리미팅 ───────────────────────────
private int packetCount;
private long windowStartTicks;
/// <summary>초당 허용 패킷 수</summary>
public int MaxPacketsPerSecond { get; set; }
/// <summary>연속 초과 횟수</summary>
public int RateLimitViolations { get; private set; }
/// <summary>
/// 패킷 수신 시 호출. 초당 제한 초과 시 true 반환.
/// </summary>
public bool CheckRateLimit()
{
long now = Environment.TickCount64;
// 1초(1000ms) 윈도우 초과 시 리셋
if (now - windowStartTicks >= 1000)
{
windowStartTicks = now;
packetCount = 0;
}
packetCount++;
if (packetCount > MaxPacketsPerSecond)
{
RateLimitViolations++;
return true; // 제한 초과
}
return false;
}
/// <summary>위반 카운트 초기화</summary>
public void ResetViolations()
{
RateLimitViolations = 0;
}
public Session(long hashKey, NetPeer peer, int maxPacketsPerSecond = 60)
{
HashKey = hashKey;
Peer = peer;
Token = null;
MaxPacketsPerSecond = maxPacketsPerSecond;
packetCount = 0;
windowStartTicks = Environment.TickCount64;
RateLimitViolations = 0;
}
}