Multi Racing Car
Java ServerSocket으로 학습용 HTTP 서버와 RFC 6455의 제한된 WebSocket 경로를 구현한 실시간 4인 레이싱 게임. 실제 지원 범위와 남은 동시성·생명주기 과제까지 기록한 3주간의 여정
해결한 문제
"추상화된 것의 내부를 이해해야 제대로 사용할 수 있다"
프레임워크 없이 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 리팩토링
2026.07.20 수정
