프로젝트 28

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 트러블 슈팅

개요게임 소켓 서버 개발을 하면서 다양한 문제점들이 발생하였다, 대부분 사소하게 무언가 빼먹던가 메모리 관리가 제대로 되지 않아 누수가 있어 발생한 문제들로 API호출 요청에 실패하거나 서버가 다운되는 크리티컬한 이슈 등 라이브 환경에서 일어나면 안될 버그가 있었다. 이슈 발생이 의심되는 부분의 코드 검토와 디버깅 로그를 삽입하여 동작 테스트를 하며 대부분의 이슈는 해결이 되었지만, 클라이언트와 통신을 통해 발생하는 경우 해당 이슈가 클라이언트에서 발생하는지, 서버에서 발생하는지에 대해 알기 어려웠다.다행히 클라이언트의 네트워크 부분을 담당하는 팀원과 자주 소통을하여 문제점을 하나하나 잡아가기 시작했고, 이러한 소통을 통해 트러블 슈팅을 더 빠르게 해결한 경험이 되었다. 하기에 내가 프로젝트를 진행하며 ..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 CI/CD 파이프라인 구축

개요Docker를 통해 컨테이너에서 서버를 띄울 준비가 완료 되었으므로 이제 빌드 및 배포 자동화를 적용하기에 적합한 환경이 되었다. 해당 프로젝트에서는 github의 gitActions을 통한 CI/CD파이프라인 구축했다. CI/CD의 장점은 로컬 환경에서 로직 수정 후 github에 push하게 될 경우 빌드 및 배포의 전 과정이 자동으로 수행되게 된다. 즉, 윈도우 환경의 Visual Studio에서 로직 변경 및 테스트 후 이상이 없어 github에 push를 하게 되면 gitActions를 통해 AWS EC2 인스턴스에 SSH연결 후 서버 재빌드 및 docker down과 up을 수행하여 최신 버전의 서버를 배포할 수 있게 된다.  github secret설정AWS EC2 인스턴스에 접속이 필요..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 docker 컨테이너화

개요환경 변수 파일 .env까지 정의하였으니 이제 서버를 배포할 일만 남았다. AWS EC2 인스턴스 내부에 C++ 서버와 PostgreSQL 서버를 docker컨테이너로 감싸 배포하였다. 관련하여 dockerfile과 docker-compose.yml파일을 작성하고 실제 docker up을 하는 것 까지 진행할 수 있다.우선 docker를 사용하기 위해 초기 단계에서 docker관련 패키지를 설치해 주어야 한다.  docker-install.sh#!/bin/bash# 실패 시 스크립트 중단set -eecho "===== Docker 설치 시작 ====="# 이전 버전 제거 (이미 설치된 경우)sudo apt-get remove -y docker docker-engine docker.io containe..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 환경변수 세팅(.env)

개요소켓 서버 관련 소스 코드에 대한 설명은 끝났다. 이제 효율적으로 빌드 후 배포하는 과정만이 남았다.궁극적으로 서버는 AWS EC2 환경에서 Docker 컨테이너에 띄워 관리해줄 것이다, 이후 CI/CD 파이프라인을 구축하여 소스코드 변경 시 자동으로 빌드 및 배포되도록 수정할 예정이다. 이를 위해 dockerfile, docker-compose, secrect 설정등을 해주어야 하는데 로컬에서만 관리하면 상관 없지만 public 레포지토리 등 다른 사람이 열람할 수 있는 곳에서 파일을 관리하게 된다면 의도하지 않게 다른 사람들에게 공개하면 안되는 데이터를 유출할 수도 있다. 따라서 환경변수 파일을 작성하여 다른 사람이 보면 안되는 내용을 숨겨서 관리하는 방법을 적용하게 되었다.  .envSERVER..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 유틸리티

개요지난 포스트를 통해 소켓 서버의 코어부터 레포지토리까지의 모든 계층에 작성된 로직을 알아보았다.보통 MVC패턴을 지킬 때 DTO, DAO등을 통해 API에 해당하는 요청 및 응답에 사용할 객체를 지정해 주는 편이었지만 소켓 서버에서는 빌드 시간을 고려하여 해당 로직은 제외하고 그냥 때에 따라 response를 제작하는 형식을 취했다. 이로 인해 코드 가독성은 그리 좋은편은 아니다, Session클래스의 process_request메서드에 action에 따른 분기 처리를 해주느라 코드 길이가 매우 길어졌다. 메서드 한개의 길이가 거의 200에 달하니 말할 것도 없다. 따라서 소켓 서버에서 어떤식으로 코드를 작성하면 좋을지에 대해선 더 공부가 필요해 보인다. 각설하고 DB트랜잭션 및 암호화를 진행하는 과..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 레포지토리 계층

개요지난 서비스계층에 이어 이번엔 트랜잭션 처리를 통한 DB와의 통신을 담당하는 레포지토리 계층에 대해 작성한 내용을 공유하고자 한다. 현재 서버에서는 회원가입, 로그인 등과 같은 인증과 방 생성, 참가, 퇴장, 조회 등 매칭 관련 트랜잭션, 게임 시작 및 종료 시 방 상태를 업데이트하는 트랜잭션을 수행한다. 데이터베이스는 PostgreSQL을 사용하였으므로 pqxx라이브러리를 사용해 DB서버와 통신하며, 고립성을 보장하여 멀티 플레이 환경에서의 동시성 처리를, 원자성을 보장하여 트랜잭션 도중 한 곳에서 예외가 발생한다면 해당 작업 이전의 작업들을 모두 롤백해 주는 것을 가장 중요시하여 로직을 작성하였다.  user_repository.h// repository/user_repository.h#pragm..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 서비스 계층

개요서비스 계층에서는 컨트롤러로 부터 요청 데이터를 받아 해당 데이터가 유효한 데이터인지, 비즈니스 로직을 수행해도 되는지 체크한 후에 서비스 로직을 수행하는 계층이다. 이 과정에서 데이터베이스를 활용한 CRUD가 필요한 경우 레포지토리에 필요한 인자를 매개변수로 전달하여 통신 결과를 토대로 응답을 작성하여 다시 컨트롤러로 리턴해주게 된다. 따라서 현재 내가 개발중인 소켓 서버에서는 서버, 세션 클래스와 같은 코어 계층과 더불어 가장 많은 코드가 작성된 로직이 바로 이 서비스 계층에 존재한다.자세한 구현 내용은 하기에 소스코드를 통해 설명하도록 하겠다.  auth_service.h// service/auth_service.h#pragma once#include #include namespace game_..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 컨트롤러 계층

개요클라이언트로 부터 요청이 들어 왔을 때 session.cpp에서 action을 분석하여 알맞은 컨트롤러 핸들러에 request를 할당해 주었었다, 이제 해당 컨트롤러 핸들러로부터 알맞은 서비스 로직으로 요청을 전달하게 된다. 서비스 로직 후 받은 리턴값을 다시 session으로 반환하게 되며, 각 response에 맞게 클라이언트에게 응답을 write하는 작업을 진행하게 된다. 이 과정에서 컨트롤러가 담당하는 부분을 구현한 로직을 공유하도록 하겠다.  controller.h// controller/controller.h#pragma once#include #include namespace game_server { class Controller { public: virtual ~..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 코어 계층(서버, 세션)

개요코어 계층에 속하는 서버의 진입점이 되는 main과 실제 서버 로직을 진행하는 server, 클라이언트 관리를 위한 session에 대한 로직을 작성하였다.하기에 코어 로직의 주요 기능에 대한 소스 파일을 설명하고자 한다.  main// main.cpp// 프로그램 진입점 및 서버 실행 파일#include "core/server.h"#include #include #include #include #include #include #include // 시그널 핸들러용 전역 서버 변수std::unique_ptr server;// 시그널 핸들러 함수void signal_handler(int signal){ spdlog::info("시그널 받음 {}, 서버 종료...", signal); if (se..

[메타버스 게임] 캐쥬얼 배틀로얄 프로젝트 계층형 아키텍쳐 구현

개요빌드 환경을 구현하였으니 본격적인 서버 구현에 앞서 구현하고자 하는 아키텍쳐를 구상해봤다.내가 개발해야할 서버에선 클라이언트 세션을 관리하고 클라이언트 요청에 따라 인증, 매칭등의 서비스 로직을 구현해야 한다. 이를 데이터베이스와 통신하여 트랜잭션 처리를 통해 검증 및 상태 업데이트를 진행해 주어야 한다. 따라서 controller를 통해 클라이언트 요청을 구분하여 각 기능에 맞는 API를 호출할 수 있도록 서비스를 핸들해 주기로 했다. 예를 들어 인증 관련은 auth, 매칭 관련은 room, 게임 생명 주기 관리는 game의 컨트롤러 타입을 지정하고, 컨트롤러 핸들러를 통해 각 API가 호출될 수 있도록 나누어줬다. 처음엔 패킷을 주고 받을 때 최대한 적은 리소스를 사용하고자했지만 게임 내 이벤트에..

728x90