일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- ucpc 2023 예선 i번
- PROJECT
- ERD
- koi 2002 중등부 1번
- string
- ccw 알고리즘
- ucpc 2024 예선 e번
- 백준 28298번
- localstorage
- MongoDB
- branch
- Express.js
- MySQL
- map
- 게임 서버 아키텍처
- 그리디
- 자바스크립트
- 백준 2623번
- Next
- 백준 28303번
- html5
- HTTP
- insomnia
- pm2
- router
- JavaScript
- Github
- 더 흔한 색칠 타일 문제
- Prisma
- ucpc 2023 예선 d번
Archives
- Today
- Total
dh_0e
[Server] 세션(Session)과 인터벌 관리자(Interval Manager)의 차이 및 사용 (with Node.js) 본문
내일배움캠프/Server
[Server] 세션(Session)과 인터벌 관리자(Interval Manager)의 차이 및 사용 (with Node.js)
dh_0e 2024. 7. 5. 21:11세션과 인터벌 관리자, 용어로만 봤을 때, 비슷해 보이는 두 개념에 대한 이해가 부족하여 강의를 듣다 정리했는데 완전히 다른 두 개념에 놀라 글을 작성한다.사실 비교하기도 웃길만큼 다른 두 개념..
세션 (Session)
목적
- 사용자의 상태 및 정보를 관리
- 사용자가 로그인했을 때 생성되고, 로그아웃하거나 일정 시간 동안 활동이 없을 때 만료됨
주요 기능
- 사용자 인증 상태를 유지
- 사용자와 관련된 데이터를 저장하고 관리 (ex. 사용자 프로필, 설정, 게임 진행 상황 등).
- 세션 타임아웃을 설정하여 일정 시간 동안 활동이 없을 경우 세션을 만료시킴
ex)
- 사용자가 게임에 로그인했을 때, 세션을 생성하여 사용자의 상태를 유지
- 사용자가 로그아웃하거나 일정 시간 동안 활동이 없을 경우 세션을 만료시키고 사용자 데이터를 정리
인터벌 관리자 (Interval Manager)
목적
- 일정 시간 간격으로 반복적으로 실행해야 하는 작업을 관리
- 주기적으로 수행해야 하는 작업을 설정하고, 이를 관리
주요 기능
- 특정 간격으로 콜백 함수를 실행
- 각 사용자가 개별적으로 주기적인 작업을 수행할 수 있도록 관리 (ex. 위치 업데이트, 게임 상태 체크 등).
- 특정 사용자의 인터벌 작업 추가, 제거, 수정을 관리
ex)
- 사용자가 게임에서 이동할 때 주기적으로 위치 업데이트를 서버에 전송
- 서버에서 일정 간격으로 게임 상태를 체크하고 업데이트
- 사용자가 게임에서 로그아웃할 때, 해당 사용자의 모든 인터벌 작업을 정리
정리
특징 | 세션(Session) | 인터벌 관리자(Interval Manager) |
목적 | 사용자의 상태 및 정보 유지 | 일정 시간 간격으로 작업 수행 |
주요 기능 | 사용자 인증 상태 관리, 사용자 데이터 저장 | 주기적인 작업 설정 및 관리, 콜백 함수 실행 |
사용 예 | 로그인/로그아웃 상태 유지, 사용자 데이터 관리 | 위치 업데이트, 게임 상태 체크 |
관리 대상 | 사용자 상태 및 정보 | 주기적인 작업 (인터벌) |
- 세션은 주로 서버 측에서 관리되고, 사용자 상호작용을 추적하고 인증하는 데 사용됨
- 반면에 인터벌 관리자는 클라이언트나 서버의 특정 작업을 정기적으로 실행하거나 관리하는 데 사용된다!
"세션"이라는 용어는 클라이언트의 상태 관리를 의미하며,
"인터벌 관리자"는 코드 실행 간격 관리를 의미하는 것
Node.js 사용 예시
- 세션과 인터벌 관리자를 함께 사용하여 유저의 세션을 관리하고, 주기적인 작업을 설정
세션 setting
sessions.js: User, Game 클래스로 생성된 객체를 담을 userSessions, gameSessions 배열 선언
// sessions.js
export const userSessions = [];
export const gameSessions = [];
user.session.js: userSession에 user 정보를 추가, 삭제 및 수정
// user.session.js
import User from '../class/model/user.class.js';
import { userSessions } from './session.js';
export const addUser = (socket, userId) => {
const user = new User(socket, userId);
userSessions.push(user);
};
export const removeUser = (socketOrUserId) => {
let index;
if (typeof socketOrUserId === 'object') {
index = userSessions.findIndex((user) => user.socket === socketOrUserId);
} else {
index = userSessions.findIndex((user) => user.userId === socketOrUserId);
}
userSessions.splice(index, 1);
};
export const editUser = (socket, replacedId) => {
removeUser(socket);
addUser(socket, replacedId);
};
export const getUser = (socketOrUserId) => {
if (typeof socketOrUserId === 'object') {
return userSessions.find((user) => user.socket === socketOrUserId);
} else {
return userSessions.find((user) => user.userId === socketOrUserId);
}
};
export const getAllUserSessions = () => {
return userSessions;
};
export const clearSession = () => {
userSessions.splice(0, userSessions.length);
};
game.session.js: gameSession에 game 정보를 추가, 삭제 및 수정
// game.session.js
import Game from '../class/model/game.class.js';
import { gameSessions } from './session.js';
export const addGame = (socket, gameId) => {
const session = new Game(gameId, socket);
gameSessions.push(session);
};
export const removeGame = (socketOrGameId) => {
let index;
if (typeof socketOrGameId === 'object') {
index = gameSessions.findIndex((game) => game.socket === socketOrGameId);
} else {
index = gameSessions.findIndex((game) => game.gameId === socketOrGameId);
}
gameSessions.splice(index, 1);
};
export const editGame = (socket, replacedId) => {
removeGame(socket);
addGame(socket, replacedId);
};
export const getGame = (socketOrGameId) => {
if (typeof socketOrUserId === 'object') {
return gameSessions.find((game) => game.socket === socketOrGameId);
} else {
return gameSessions.find((game) => game.gameId === socketOrGameId);
}
};
export const getAllGameSessions = () => {
return gameSessions;
};
export const clearSession = () => {
gameSessions.splice(0, gameSessions.length);
};
인터벌 관리자 setting
interval.manager.js: addUser에서 userId를 key값으로 하는 value는 또 Map 객체이며 type을 key값으로 하는 value에 setInterval 함수가 반환한 intervalId가 저장됨
// interval.manager.js
class IntervalManager {
constructor() {
this.intervals = new Map();
}
// userId가 key값으로 있는 value에 Map을 만들어 type을 key값으로 갖는 value에 Interval 생성(callBack 함수 interval 마다 실행)
addUser(userId, callBack, interval, type = 'user') {
if (!this.intervals.has(userId)) {
this.intervals.set(playerId, new Map());
}
this.intervals.get(playerId).set(type, setInterval(callBack, interval));
}
// userId로 저장된 모든 데이터 삭제
removeUser(userId) {
if (this.intervals.has(userId)) {
const userIntervals = this.intervals.get(playerId);
// forEach에 map 객체를 넣으면 첫 번째 인자에 value값이 들어가므로
// intervalId에 setInterval함수가 반환한 ID가 들어가 이를 clearInterval 시키는 원리
userIntervals.forEach((intervalId) => {
clearInterval(intervalId);
this.intervals.delete(playerId);
});
}
}
// userId로 저장된 interval중 type이 key값으로 저장된 interval들을 삭제
removeInterval(userId, type) {
if (this.intervals.has(userId)) {
const userIntervals = this.intervals.get(userId);
if (userIntervals.has(type)) {
clearInterval(userIntervals.get(type));
userIntervals.delete(type);
}
}
}
clearAll() {
// 마찬가지로 userIntervals에 value인 map 객체가 들어가고
this.intervals.forEach((userIntervals) => {
// intervalId에는 key 값인 type 대신 value 값인 setInterval함수가 반환한 ID가 들어감
userIntervals.forEach((intervalId) => clearInterval(intervalId));
});
this.intervals.clear();
}
}
export default IntervalManager;
- 이제 User나 Game class에 IntervalManager를 추가하여 주기적인 작업을 실행할 수 있으며 그 class를 session에 넣어 한꺼번에 관리할 수 있다!
'내일배움캠프 > Server' 카테고리의 다른 글
[Server] 게임 서버 아키텍처 (0) | 2024.08.06 |
---|---|
[Server] 강의 내용 정리 (3) (Latency, 추측 항법(Dead Reckoning)) (0) | 2024.07.04 |
[Server] 강의 내용 정리 (2) (Unity, Unity UGUI) (0) | 2024.06.28 |
[Server] 강의 내용 정리 (1) (net 모듈, Socket event, Buffer 객체) (0) | 2024.06.27 |