C#으로 서버 열기
-
기존 Node.js 로 구성한 서버와 구조적 차이가 엄청 나는 것 같다..
-
일부 강의에 있는 파일들과 클라이언트의 C# 파일들을 분석해서 패킷을 해석 및 처리하는 로직까지 구현하였다.
-
파일 구조가 너무 꼬여있어서 도식화를 통해 이해하기 쉽도록 정리할 예정이다.
핸들러 맵퍼
- 서버마다 핸들러를 매핑해주는 매니저가 있었으면해서 베이스를 미리 만들었다.
public abstract class HandlerManagerBase<TPacketType, TGamePacket>
where TPacketType : Enum
where TGamePacket : class
{
// 스레드 안전한 핸들러 저장소
protected ConcurrentDictionary<TPacketType, Func<TGamePacket, Task>> Handlers
= new ConcurrentDictionary<TPacketType, Func<TGamePacket, Task>>();
// 핸들러 등록 메서드
protected void RegisterHandler(TPacketType packetType, Func<TGamePacket, Task> handler)
{
Handlers[packetType] = handler;
}
// 생성자에서 핸들러 자동 등록
protected HandlerManagerBase()
{
RegisterHandlers();
}
// 추상 메서드로 핸들러 등록 구현 강제
protected abstract void RegisterHandlers();
// 패킷 처리 메서드
public virtual async Task OnRecvPacketAsync(TPacketType packetType, TGamePacket packet)
{
if (Handlers.TryGetValue(packetType, out var handler))
{
try
{
await handler(packet);
}
catch (Exception ex)
{
// 공통 예외 처리
await HandleExceptionAsync(packetType, packet, ex);
}
}
else
{
// 핸들러가 없는 경우 로깅
await HandleMissingHandlerAsync(packetType, packet);
}
}
}
- 이제 이를 이용해 서버마다 핸들러를 매핑해주는 매니저를 생성하면 된다!
class HandlerManager : HandlerManagerBase<ePacketType, GamePacket>
{
// 스레드 안전한 싱글톤
private static readonly object _lock = new object();
private static HandlerManagerBase<ePacketType, GamePacket> _instance;
// 싱글톤 인스턴스 속성
public static HandlerManagerBase<ePacketType, GamePacket> Instance
{
get
{
// 이중 검사 락킹 (Double-Check Locking)
if (_instance == null)
{
lock (_lock)
{
// 인스턴스가 없는 경우에만 생성
_instance ??= CreateInstance();
}
}
return _instance;
}
}
protected static HandlerManagerBase<ePacketType, GamePacket> CreateInstance()
{
return new HandlerManager();
}
protected override void RegisterHandlers()
{
// 수동 핸들러 등록 예시
RegisterHandler(ePacketType.LOGIN_REQUEST, LoginHandler);
}
}
- 이후 매핑된 핸들러를 사용해준다!
public override async void OnRecvPacket(Packet packet)
{
await HandlerManager.Instance.OnRecvPacketAsync(packet.Type, packet.GamePacket);
}
한줄 평 + 개선점
- 구조가 많이 복잡하다..