백엔드 경험
- Redis관련 흐름 정리
flowchart TB
Client["Client (Socket.IO)"]
GameService["GameService"]
Redis["Redis"]
HTTP["HTTP Service"]
Client <--> |Socket Events| GameService
GameService <--> |Data Storage/Pub-Sub| Redis
GameService --> |Quiz Data| HTTP
flowchart TB
Room["Room:{gameId}
- host
- status
- quizSetId
- quizCount"]
Player["Player:{clientId}
- gameId
- playerName
- position
- score"]
RoomQuiz["RoomQuiz:{gameId}:{quizId}
- quiz
- answer
- limitTime"]
Leaderboard["Leaderboard:{gameId}
Sorted Set of players"]
Room --> Player
Room --> RoomQuiz
Room --> Leaderboard
flowchart LR
Waiting["대기중"] --> Playing["게임중"]
Playing --> QuizStart["퀴즈 시작"]
QuizStart --> QuizEnd["퀴즈 종료"]
QuizEnd --> |다음 퀴즈| QuizStart
QuizEnd --> |마지막 퀴즈| GameEnd["게임 종료"]
- 주요 이벤트 흐름도
sequenceDiagram
participant C as Client
participant GS as GameService
participant R as Redis
participant H as HTTP Service
C->>GS: updatePosition
GS->>R: Set Player Position
R-->>C: Broadcast Position Update
C->>GS: startGame
GS->>H: Get Quiz Data
GS->>R: Initialize Game State
R-->>C: Broadcast Game Start
Note over GS,R: Redis Pub/Sub Events
R->>GS: Timer Event
GS->>C: START_QUIZ_TIME
R->>GS: Scoring Event
GS->>C: END_QUIZ_TIME
C->>GS: disconnect
GS->>R: Update Room State
R-->>C: Broadcast Player Exit
- 구체적인 예시
sequenceDiagram
participant Player1 as 방장(홍길동)
participant Player2 as 참가자(김철수)
participant Game as GameService
participant Redis as Redis
participant HTTP as HTTP API
Note over Player1,Player2: 게임 시작 전
Player1->>Game: 방 생성 (게임 ID: room123)
Game->>Redis: 방 정보 저장<br/>Room:room123 = {host: "홍길동"}
Player2->>Game: 방 입장
Game->>Redis: 플레이어 정보 저장<br/>Player:김철수 = {gameId: "room123"}
Redis-->>Player1: 플레이어 입장 알림
Note over Player1,Player2: 게임 시작
Player1->>Game: 게임 시작 요청
Game->>HTTP: 퀴즈 데이터 요청
HTTP-->>Game: 퀴즈 데이터 응답<br/>(예: "자바스크립트 기초" 퀴즈셋)
Note over Player1,Player2: 첫 번째 퀴즈
Game->>Redis: 퀴즈 데이터 저장
Redis-->>Player1: 퀴즈 시작<br/>"var와 let의 차이점은?"
Redis-->>Player2: 퀴즈 시작<br/>"var와 let의 차이점은?"
Note over Player1,Player2: 답변 제출 (위치 기반)
Player1->>Game: 위치 이동 (1번 영역)
Player2->>Game: 위치 이동 (3번 영역)
Game->>Redis: 위치 정보 저장
Note over Player1,Player2: 채점
Game->>Redis: 채점 결과 저장<br/>Player1: 정답(+1000점)<br/>Player2: 오답(+0점)
Redis-->>Player1: 결과 발표
Redis-->>Player2: 결과 발표
// 1. 방 생성 시점의 Redis 데이터
{
"Room:room123": {
"host": "player1",
"status": "waiting",
"quizSetId": "js-basic-101",
"maxPlayerCount": "4",
"quizCount": "5"
},
// 플레이어 입장
"Player:player1": {
"gameId": "room123",
"playerName": "홍길동",
"positionX": "0.5",
"positionY": "0.5",
"isAnswerCorrect": "0"
},
"Player:player2": {
"gameId": "room123",
"playerName": "김철수",
"positionX": "0.5",
"positionY": "0.5",
"isAnswerCorrect": "0"
},
// 게임 시작 후 퀴즈 데이터
"RoomQuiz:room123:quiz1": {
"quiz": "var와 let의 차이점은?",
"answer": "2", // 2번이 정답
"limitTime": "30",
"choiceCount": "4"
},
"RoomQuizChoices:room123:quiz1": {
"1": "아무 차이 없다",
"2": "let은 블록 스코프, var는 함수 스코프",
"3": "let만 재선언 가능",
"4": "var만 호이스팅 된다"
},
// 리더보드
"Room:room123:leaderboard": {
"player1": "1000",
"player2": "0"
}
}
- 1:n:n:n 관계 조회, 페이징
flowchart TB
subgraph "QuizSet 조회"
A[Start] --> B[QuizSet Repository]
B --> C[QuizSets]
C -->|Empty| D[Return Empty Result]
C -->|Not Empty| E[Extract QuizSet IDs]
end
subgraph "Quiz 조회"
E --> F[Quiz Repository]
F -->|WHERE IN quizSetIds| G[Quizzes]
G --> H[Extract Quiz IDs]
end
subgraph "Choice 조회"
H --> I[Choice Repository]
I -->|WHERE IN quizIds| J[Choices]
end
subgraph "메모리 매핑"
J --> K[Group Choices by QuizId]
G --> L[Group Quizzes by QuizSetId]
C --> M[Map to DTOs]
K --> M
L --> M
end
M --> N[Return Result]
1: N : N: N의 조회가 쿼리 단 3번으로 끝난다! 페이징도 가능하다!
- 1:N:N:N 에서 변경감지를 통한 수정
flowchart TB
Start[시작] --> Transaction[트랜잭션 시작]
Transaction --> FindQuizSet[퀴즈셋 조회<br/>with Relations]
FindQuizSet --> |Not Found| Error[NotFoundException]
FindQuizSet --> |Found| BasicUpdate[기본 필드 업데이트]
subgraph "기본 필드 업데이트"
BasicUpdate --> |title 존재| UpdateTitle[제목 업데이트]
BasicUpdate --> |category 존재| UpdateCategory[카테고리 업데이트]
end
BasicUpdate --> CheckQuizList{퀴즈 리스트<br/>존재?}
CheckQuizList --> |No| SaveChanges[변경사항 저장]
CheckQuizList --> |Yes| UpdateQuizzes[퀴즈 업데이트]
subgraph "퀴즈/선택지 업데이트"
UpdateQuizzes --> ProcessQuiz[각 퀴즈 처리]
ProcessQuiz --> |신규| CreateQuiz[새 퀴즈 생성]
ProcessQuiz --> |기존| UpdateQuiz[기존 퀴즈 업데이트]
UpdateQuiz --> CheckChoices{선택지<br/>존재?}
CreateQuiz --> CheckChoices
CheckChoices --> |Yes| UpdateChoices[선택지 업데이트]
CheckChoices --> |No| SaveQuiz[퀴즈 저장]
UpdateChoices --> SaveQuiz
end
UpdateQuizzes --> SaveChanges
SaveChanges --> Return[결과 반환]
sequenceDiagram
participant C as Controller
participant S as Service
participant T as Transaction
participant M as Entity Manager
participant E as Entities
C->>S: update(id, dto)
S->>T: transaction 시작
T->>M: findOne with relations
M->>E: Load QuizSet + Relations
Note over E: 변경 감지 시작
E->>E: 기본 필드 업데이트
loop 각 퀴즈에 대해
E->>E: 퀴즈 필드 업데이트
loop 각 선택지에 대해
E->>E: 선택지 필드 업데이트
end
end
E->>M: 변경사항 저장
M->>T: Commit
T->>S: 결과 반환
S->>C: 응답
'개발일지' 카테고리의 다른 글
24. 11. 19. 개발일지 // test-code 의존성 수정, redis 구독 리팩토링, 진행중게임에 들어올수없음 (0) | 2024.11.20 |
---|---|
24. 11. 18. 개발일지 // api vs 서비스주입, redis 캐시 (1) | 2024.11.19 |
24. 11. 17. 개발일지 redis 탐색 (0) | 2024.11.18 |
24.11.14. 개발일지 // 자동배포, 깃헙액션에서 db test, ssh 터널링 db 연결 (1) | 2024.11.14 |
[week2-수요일] 개발일지 // 테이블설계 (0) | 2024.08.28 |