1. Service 클래스 개요
기본 개념
Service 클래스는 서버 또는 클라이언트용 세션의 생성을 관리하고, 세션 풀링과 I/O 작업을 추상화한 베이스 클래스입니다.
Service 클래스는 Session 객체를 생성하는 팩토리 패턴을 도입했으며, shared_ptr를 사용하여 객체의 메모리 관리를 안전하게 처리합니다.
ServerService와 ClientService가 Service를 상속받아 특정 동작(시작, 종료 등)을 커스터마이징합니다.
2. 코드 분석 및 한 줄 한 줄 설명
Service.h
전처리 지시문 및 헤더 포함
#pragma once
#include "NetAddress.h"
#include "IocpCore.h"
#include "Listener.h"
#include <functional>
#pragma once: 중복 인클루드를 방지합니다.
NetAddress, IocpCore, Listener: 네트워크 주소, IOCP 코어, 리스너 클래스를 포함합니다.
<functional>: SessionFactory와 같은 함수 객체를 정의하기 위해 필요합니다.
ServiceType 열거형 정의
enum class ServiceType : uint8
{
Server,
Client
};
ServiceType: 서비스의 타입을 정의합니다. Server는 서버용 서비스, Client는 클라이언트용 서비스입니다.
타입 정의 및 SessionFactory 함수 객체
using SessionFactory = function<SessionRef(void)>;
SessionFactory: 세션 객체를 생성하는 콜백 함수 타입입니다. function을 사용해 함수 포인터나 람다 함수를 받습니다.
using IocpCoreRef = std::shared_ptr<class IocpCore>;
using IocpObjectRef = std::shared_ptr<class IocpObject>;
using SessionRef = std::shared_ptr<class Session>;
using ListenerRef = std::shared_ptr<class Listener>;
using ServerServiceRef = std::shared_ptr<class ServerService>;
shared_ptr을 사용하여 스마트 포인터 타입을 정의합니다. 객체의 메모리 관리와 참조 카운트를 안전하게 처리합니다.
Service 클래스 정의
class Service : public enable_shared_from_this<Service>
enable_shared_from_this: shared_ptr로 관리되는 객체가 자기 자신의 shared_ptr를 안전하게 반환할 수 있게 합니다.
생성자 및 소멸자
Service(ServiceType type, NetAddress address, IocpCoreRef core, SessionFactory factory, int32 maxSessionCount = 1);
virtual ~Service();
- 생성자:
ServiceType, 네트워크 주소, IocpCore, SessionFactory, 세션 최대 수를 초기화합니다.
- 소멸자: 가상 소멸자를 선언하여 상속받은 클래스에서 소멸자가 제대로 호출되도록 합니다.
가상 함수 Start
virtual bool Start() abstract;
Start 함수는 순수 가상 함수입니다. 하위 클래스에서 반드시 구현해야 합니다.
CloseService 함수
virtual void CloseService();
- 서비스 종료를 처리합니다.
ServerService와 같은 하위 클래스에서 오버라이드할 수 있습니다.
세션 관리 함수
SessionRef CreateSession();
void AddSession(SessionRef session);
void ReleaseSession(SessionRef session);
CreateSession: SessionFactory를 통해 새로운 세션 객체를 생성합니다.
AddSession: 세션 객체를 세션 목록에 추가하고, 현재 세션 개수를 증가시킵니다.
ReleaseSession: 세션을 목록에서 제거하고, 현재 세션 개수를 감소시킵니다.
세션 정보 반환 함수
int32 GetCurrentSessionCount() { return _sessionCount; }
int32 GetMaxSessionCount() { return _maxSessionCount; }
GetCurrentSessionCount: 현재 세션 개수를 반환합니다.
GetMaxSessionCount: 최대 허용 세션 개수를 반환합니다.
Service 타입과 네트워크 주소 반환
ServiceType GetServiceType() { return _type; }
NetAddress GetNetAddress() { return _netAddress; }
멤버 변수
USE_LOCK;
ServiceType _type;
NetAddress _netAddress;
IocpCoreRef _iocpCore;
set<SessionRef> _sessions;
int32 _sessionCount = 0;
int32 _maxSessionCount = 0;
SessionFactory _sessionFactory;
USE_LOCK: 멀티스레드 환경에서 세션 관리 시 동기화를 위한 잠금 사용.
_type: 서비스 타입(Server 또는 Client).
_netAddress: 네트워크 주소 정보.
_iocpCore: IOCP 객체를 관리하는 스마트 포인터.
_sessions: 세션 목록을 저장하는 set 컨테이너.
_sessionCount: 현재 활성화된 세션 개수.
_maxSessionCount: 최대 세션 개수.
_sessionFactory: 세션을 생성하는 함수 객체.
ServerService 클래스
생성자
ServerService(NetAddress address, IocpCoreRef core, SessionFactory factory, int32 maxSessionCount = 1);
NetAddress, IocpCore, SessionFactory를 초기화합니다.
Start 함수
bool ServerService::Start()
{
if (CanStart() == false)
return false;
_listener = make_shared<Listener>();
if (_listener == nullptr)
return false;
ServerServiceRef service = static_pointer_cast<ServerService>(shared_from_this());
if (_listener->StartAccept(service) == false)
return false;
return true;
}
CanStart(): 세션 팩토리가 유효한지 확인합니다.
Listener 객체 생성: make_shared를 통해 Listener를 생성합니다.
StartAccept: 리스너가 클라이언트 연결을 수락하도록 설정합니다.
CloseService 함수
void ServerService::CloseService()
{
Service::CloseService();
}
main 함수
int main()
{
SocketUtils::Init();
ServerServiceRef service = make_shared<ServerService>(
NetAddress(L"127.0.0.1", 7777),
make_shared<IocpCore>(),
[]() { return make_shared<GameSession>(); },
100);
ServerService 객체 생성: NetAddress, IocpCore, 세션 팩토리 함수, 최대 세션 수를 전달합니다.
GameSession: Session을 상속한 게임 세션을 생성합니다.
IOCP 처리 스레드 실행
for (int32 i = 0; i < 5; i++)
{
GThreadManager->Launch([=]()
{
while (true)
{
service->GetIocpCore()->Dispatch();
}
});
}
- IOCP Core의
Dispatch를 호출해 이벤트를 처리합니다. 스레드 5개를 실행합니다.
자원 정리
GThreadManager->Join();
SocketUtils::Clear();
- 스레드 종료를 대기하고 소켓 자원을 정리합니다.