🏆
13:30-14:10 (40분)

성경 타자경기 앱 업그레이드

QR로 접속 → 실시간 타자 대회

🎯 학습 목표

  • Socket.IO를 활용한 실시간 멀티플레이어 구현
  • QR 코드 생성 및 입장 시스템 구축
  • 실시간 리더보드 업데이트
  • 방 관리 및 게임 상태 동기화

💻 실습: 단계별 진행

STEP 1프로젝트 구조 설정 (5분)

🤖 첫 번째 프롬프트

Next.js와 NestJS를 사용한 모노레포 구조를 만들어줘. Next.js는 apps/web 폴더에, NestJS는 apps/api 폴더에 생성해줘. pnpm workspace를 사용해줘. Socket.IO 패키지도 양쪽에 설치해줘.

📁 생성될 구조

typing-race/
├── apps/
│   ├── api/          # NestJS 백엔드
│   └── web/          # Next.js 프론트엔드
├── package.json      # 루트 패키지
└── pnpm-workspace.yaml

STEP 2백엔드: Socket.IO 게이트웨이 구현 (10분)

🤖 두 번째 프롬프트

NestJS에 Socket.IO 게이트웨이를 만들어줘. 다음 이벤트를 처리해줘:
1. joinRoom: 사용자가 방에 입장
2. typing: 타이핑 진행 상황 전송
3. complete: 완료 시각 기록
4. disconnect: 연결 해제 처리

각 방은 최대 100명까지 참가 가능하게 해줘. 방 정보는 메모리에 Map으로 저장해줘.

🔍 핵심 로직

@WebSocketGateway()
export class TypingGateway {
  @SubscribeMessage('joinRoom')
  handleJoinRoom(client: Socket, data: { roomId, name }) {
    client.join(data.roomId);
    // 방에 있는 모든 사용자에게 알림
    this.server.to(data.roomId).emit('playerJoined', data);
  }
  
  @SubscribeMessage('typing')
  handleTyping(client: Socket, data: { roomId, progress }) {
    // 실시간으로 다른 참가자들에게 진행 상황 전송
    client.to(data.roomId).emit('playerProgress', data);
  }
}

STEP 3MariaDB 연동 및 기록 저장 (8분)

🤖 세 번째 프롬프트

Prisma를 사용해서 MariaDB와 연결해줘. TypingResult 모델을 만들어줘:
- roomId (문자열)
- playerName (문자열)
- text (문자열, 타이핑한 문구)
- wpm (숫자, 분당 타자수)
- accuracy (숫자, 정확도)
- completedAt (날짜)

게임 완료 시 결과를 저장하는 API도 만들어줘.

STEP 4프론트엔드: 호스트 화면 구현 (8분)

🤖 네 번째 프롬프트

Next.js로 호스트 화면을 만들어줘.
1. "방 만들기" 버튼 - 6자리 방 코드 생성
2. QR 코드 표시 - qrcode.react 라이브러리 사용
3. 참가자 목록 실시간 표시
4. "게임 시작" 버튼
5. 실시간 리더보드 - 진행률과 순위 표시

Socket.IO 클라이언트로 백엔드와 연결해줘.

🎨 화면 구성

대기 화면

  • • QR 코드 (큼직하게)
  • • 방 코드 (큰 글씨)
  • • 참가자 수
  • • 시작 버튼

게임 화면

  • • 목표 성경 구절
  • • 실시간 순위표
  • • 각 참가자 진행률
  • • 타이머

STEP 5프론트엔드: 참가자 화면 구현 (9분)

🤖 다섯 번째 프롬프트

참가자용 페이지를 만들어줘.
1. 방 코드 입력 화면
2. 이름 입력
3. 대기 화면 - "호스트가 게임을 시작할 때까지 기다려주세요"
4. 타이핑 화면 - 성경 구절과 입력 창
5. 결과 화면 - 내 순위, WPM, 정확도

모바일 최적화도 해줘. 세로 모드 화면에 맞게.

📱 모바일 UX 고려사항

  • • 큰 터치 영역 (버튼 최소 44x44px)
  • • 가상 키보드 공간 확보
  • • 자동 스크롤 방지
  • • 확대/축소 방지 (viewport 설정)

🔥 실시간 동기화 로직

1️⃣ 방 입장

// 클라이언트
socket.emit('joinRoom', { roomId: '123456', name: '김목사' });

// 서버 → 모든 참가자에게 브로드캐스트
socket.to(roomId).emit('playerJoined', { name: '김목사' });

2️⃣ 실시간 타이핑 진행

// 클라이언트 - 키 입력마다 전송
onKeyPress(() => {
  socket.emit('typing', { 
    roomId, 
    progress: currentLength / totalLength,
    wpm: calculateWPM()
  });
});

3️⃣ 완료 처리

// 클라이언트
socket.emit('complete', { roomId, result: {...} });

// 서버 → DB 저장 + 모두에게 알림
await prisma.typingResult.create({ data: result });
socket.to(roomId).emit('playerCompleted', result);

🚀 확장 아이디어

👥 팀전 모드

청년부 vs 장년부 팀 대항전

🎤 음성 카운트다운

"3, 2, 1, 시작!" 음성 출력

📊 통계 대시보드

역대 기록, 평균 WPM 차트

🎁 리워드 시스템

배지 획득, 레벨업 시스템

✅ 완성 체크리스트

👨‍🏫 강사 노트

⏰ 시간 배분: 백엔드(15분), 프론트엔드(20분), 테스트(5분)

📱 데모 준비: 실제 휴대폰으로 접속하여 시연. QR 코드 스캔하는 장면 보여주기

🎯 핵심 메시지: "오전 앱이 오후에는 100명이 동시에 쓸 수 있는 서비스가 되었습니다!"

🔧 트러블슈팅: 방화벽/네트워크 이슈 대비, 핫스팟 사용법 준비

🎉 분위기: 첫 실시간 앱 완성! 환호 유도. 실제로 게임 한 판 진행해보기