Multi Racing Car - 프레임워크 없이 만드는 멀티플레이 게임
"추상화된 것의 내부를 이해해야 제대로 사용할 수 있다"
프레임워크 없이 ServerSocket으로 프로젝트에 필요한 HTTP 처리 범위를 구현하고, RFC 6455 문서를 읽으며 opening handshake와 짧은 텍스트 frame 경로를 직접 다룬 실시간 멀티플레이 레이싱 게임입니다.
- 핵심 도전: Spring Boot 없이 HTTP/WebSocket 직접 구현, 멀티스레드 동시성 제어, 아키텍처 설계 원칙 적용
🔗 링크
- 🎮 게임 플레이하기 - 현재 운영 중인 게임을 직접 플레이할 수 있습니다
- GitHub Repository - 프로젝트 소스 코드

🎮 주요 기능
게임 모드
- 멀티플레이: 4명 자동 매칭 실시간 대전
- 싱글 플레이: 1 vs 3 AI 대전
게임 규칙
- 5라운드 진행, 각 라운드마다 50% 확률로 0-1칸 이동
- 최장거리 도달자 우승
🛠 기술 스택
Backend
- 언어: Java 21
- 빌드: Gradle 8.14
- 서버: ServerSocket (GET·정적 응답 범위의 HTTP 구현)
- 실시간 통신: WebSocket (학습 목적의 제한된 RFC 6455 구현)
- 동시성: 연결당 Thread, 방별 ScheduledExecutorService, ConcurrentHashMap
Frontend
- HTML/CSS/JavaScript
- WebSocket Client API
🔧 핵심 구현 내용
1. HTTP 서버 구현
- ServerSocket을 사용한 학습용 HTTP 서버
- 프로젝트에서 사용하는 GET 요청 라인과 헤더 파싱
- MIME Type 설정 및 정적 파일 서빙
2. WebSocket 프로토콜 구현
RFC 6455를 참고해 프로젝트에 필요한 범위만 직접 구현
- Handshake: Sec-WebSocket-Key와 GUID로 Sec-WebSocket-Accept 계산
- Frame 처리: payload 길이 추출과 짧은 단일 텍스트 frame 처리
- Masking: 브라우저가 보낸 masking key로 XOR 디코딩
이 구현은 짧은 단일 텍스트 프레임이라는 프로젝트의 happy path에 맞춘 학습용 구현입니다. 확장 길이(126/127), fragmentation, partial read, opcode·MASK 검증, ping/pong과 정상 종료 제어 프레임까지 포괄하는 범용 WebSocket 서버는 아닙니다.
3. 멀티플레이 게임 로직
- 4명 자동 매칭 시스템 및 대기열 관리
- 게임룸 격리 (여러 게임 동시 진행)
- 5라운드 자동 진행 및 우승자 결정
- 싱글 플레이 AI 대전 모드
4. 멀티스레드 환경
- 연결마다 새 Thread를 생성해 동시 접속 처리
- ConcurrentHashMap의 보장 범위와 원자적 연산 구분
- 세션/게임룸 생명주기 관리
5. 아키텍처 개선
- SRP: God Object를 3개 서비스로 분리
- DIP: GameEventPublisher 인터페이스 추상화
- Value Object: Nickname, Position, Round 등
📚 개발 과정 상세 회고
프레임워크 없이 개발하며 겪은 시행착오와 해결 과정을 5편의 글로 정리했습니다:
1. 오픈미션 주제 선정: 프레임워크 없이 Multi Racing Car Game 만들기
- 혼자 프로젝트를 진행한 이유
- Spring Boot 대신 ServerSocket을 선택한 배경
- 단계적 확장 전략 (3주 계획)
2. WebSocket을 바닥부터 구현하기
- RFC 6455 문서 읽기
- Handshake 및 Frame 파싱 구현 (3일간의 삽질)
- 세션 관리 및 게임룸 격리
3. 멀티스레드 환경에서 살아남기
- Thread로 동시 접속 해결
- Race Condition과 ConcurrentHashMap의 한계
- Repository 참조 누적과 정리 타이밍 분석
4. God Object를 해체하고 설계 개선하기
- 여러 책임이 섞인 GameService를 역할별 서비스로 분리
- 구체적인 WebSocket·SessionManager 의존을 GameEventPublisher 포트 뒤로 역전
- Singleton 제거 및 생성자 주입
5. 프레임워크 없이 개발하며 배운 것들
- 프레임워크의 가치 이해
- 원본 문서 읽기의 중요성
- 모르는 것을 스스로 배우는 법
💡 배운 점
기술적 이해
- HTTP/WebSocket 프로토콜 동작 원리
- 멀티스레드 프로그래밍과 동시성 제어
- 가비지 컬렉션의 한계와 명시적 리소스 관리
설계 원칙
- SRP, DIP 등 객체지향 원칙의 실전 적용
- 도메인과 인프라의 분리
🏷️ 기술 스택 태그
Java WebSocket HTTP ServerSocket RFC 6455 멀티스레드 ConcurrentHashMap SRP DIP 리팩토링