레디스 용도
- TowerDefenseOnline 프로젝트에서 Redis는 게임 데이터를 효율적이고 안정적으로 관리하기 위해 사용
- 특히, 빠른 데이터 접근 속도와 지속성 있는 DB 역할을 수행
- 인메모리 데이터 관리 방식에서 발생할 수 있는 데이터 유실 문제를 해결하기 위한 솔루션
- 우리 프로젝트의 특징인 TCP통신이기 때문에 실시간 게임 플레이 중에도 데이터 일관성을 유지하면서 높은 성능을 제공
레디스가 쓰이는 곳
기능
- 로그인
- 매칭
- 상태 동기화
- 타워 구매
- 몬스터 생성
- 타워 공격
- 몬스터 공격
- 넥서스 HP업데이트
- 몬스터 처치
- 게임 오버
- 게임 종료
로그인 ( redisClient.hmset(`user:${user.userId}`, userData); )
클라이언트에서 request로 payloadData가 들어오면
const { id, password } = requestMessage;
이 두가지 정보가 들어오게 됩니다.
그렇다면 회원가입 할때 DB에 user가 있는지 확인하고
비밀 번호 같은 경우는 로그인에서 bcrypt를 사용해서 해쉬값으로 넣은것을 확인해줍니다.
DB에 있는 아이라면
로그인 시점을 갱신해주고 jwt를 생성해 준다.
서버에 보내는 데이터는
sendPayload = {
success: true,
message: '로그인 성공',
token: token,
failCode: failCode.values.NONE,
};
이렇게 4개를 보내주고 우리는 지금까지 인메모리 형식으로
const user = new User(socket, isExistUserInDB.userId, isExistUserInDB.highScore);
redis에 해당 user정보를 저장해둬야함
await addUser(user);
userSession에다가 socket과 userId(아이디임), 최고 점수를 저장해왔기 때문에
우선적으로 redis에 넣어야할 데이터는 socket, userId, highScore, jwt입니다.
그럼 어떻게 사용하는지 redisConnect.js에 적어보게습니다.
export const RedisManager = {
addUser: async (user) => {
try {
const userData = {
socketId: user.socket.id,
userId: user.id,
highScore: user.highScore,
jwt: user.socket.token,
};
// Redis에 Hash 형식으로 저장
await redisClient.hmset(`user:${user.id}`, userData);
console.log(`유저 정보가 Redis에 저장되었습니다: user:${user.id}`);
} catch (error) {
console.error('Redis에 유저 정보 저장 중 오류 발생:', error);
}
},
getUser: async (userId) => {
try {
// Redis에서 저장된 유저 데이터를 가져옴
const userData = await redisClient.hgetall(`user:${userId}`);
if (Object.keys(userData).length === 0) {
console.log(`유저 정보가 Redis에 존재하지 않습니다: user:${userId}`);
return null;
}
console.log(`유저 정보 불러오기 성공: user:${userId}`, userData);
return userData;
} catch (error) {
console.error('Redis에서 유저 정보 불러오기 중 오류 발생:', error);
return null;
}
},
매칭 ()
클라이언트에서 서버로 보내주는 데이터가 아무것도 없습니다.
일단 matchHandler 부분을 보면 User의 Socket을 가져오는 부분을 redis에서 가져와야 합니다.
const user = getUserBySocket(socket);
예시로 적어보자면
const user1 = await RedisManager.getUserBySocket(socket);
이런식으로 불러오면 됩니다.
RedisManager에 getUserBySocket부분만 추가했습니다.
그리고 난 후
// 유저 세션 전체 다들고와서 홀수면 gameSession 만들고 아닐 때는 추가만 하는 부분을 작업해야합니다.
addUserInMatchSession(user);
- 상태 동기화
- 타워 구매
- 몬스터 생성
- 타워 공격
- 몬스터 공격
- 넥서스 HP업데이트
- 몬스터 처치
- 게임 오버
- 게임 종료
작성 하던 도중 시간 상의 문제로 user데이터를 저장하던 부분을 redis에 저장해서 불러오는 방식만 진행하기로 했습니다.
'기타' 카테고리의 다른 글
모의 면접 질문 (3가지) (0) | 2024.09.29 |
---|---|
2024-08-09 금요일 TIL 마무리 (0) | 2024.08.09 |
Stack과 Heap의 차이점 (0) | 2024.07.08 |
혼자 포폴하면서 느낀점 - 2 (0) | 2024.06.24 |
혼자 포폴하면서 느낀점 (0) | 2024.06.21 |