커넥션 핸들러 :
- 웹소켓과 TCP에서는 데이터 통신을 위해 Connection을 맺어야
하는데 그 Connection을 어떻게 관리할 것인지, 어떻게 핸들링할 것인지
- 서버에서 유저를 위한 데이터를 생성해 저장할 수 있다.
1. 기획 리마인드
스테이지 관련 내용을 리마인드 해봅시다.
☑️ 스테이지에 따라서 더 높은 점수 획득
- 0점 , 1스테이지
- 1000점, 2스테이지
- 위와 같이 점수로 나뉘어서 스테이지 구분
- 스테이지가 올라갈수록 시간당 높은 점수 획득 가능
- ex) 1스테이지 = 1점 per 1s, 2스테이지 = 2점 per 1s
‘0점, 1스테이지’ 의 내용을 구현하려면 유저는 연결(계정)이
생성되는 즉시 스테이지에 관한 정보를 가지고 있어야합니다.
해당 내용에 따라 배운 내용을 토대로 만들어봅시다
그럼 스테이지를 위한
models(현재 존재하는 파일)/stage.model.js를 만들어
stage와 관련된 필요 기능을 구현해보겠습니다.
models/stage.model.js
// key : uuid, value : array -> stage 정보는 배열
const stages = {};
// 스테이지 초기화
const createStage = (uuid) => {
stages[uuid] = [];
};
// 유저에게 현재 스테이지
const getStage = (uuid) => {
return stages[uuid];
};
// 유저에게 제공할 스테이지
const setStage = (uuid, id) => {
return stages[uuid].push({ id });
};
export { createStage, getStage, setStage };
그럼 스테이지가 제공되야 할 위치는 언제일까요?
처음에는 유저가 게임에 접속했을 때 입니다.
유저가 처음 접속했을 장소인
register.handler.js의 registerHandler함수로 가봅시다.
handlers/register.handler.js
import { addUser } from '../models/user.model.js';
import { v4 as uuid } from 'uuid';
import { handleDisconnect } from './helper.js';
const registerHandler = (io) => {
io.on('connection', (socket) => {
// 최초 커넥션을 맺은 이후 발생하는 각종 이벤트를 처리하는 곳
const userUUID = uuid;
// v4 메서드를 바탕으로 uuid를 생성 및 담아준다.
addUser({ uuid: userUUID, socketId: socket.id });
// socketId는 socket.id로 받아온다.
//이 시점이 현재 유저가 막 접속을 했을 시점 입니다.
//접속 해제시 이벤트
socket.on('disconnect', (socket) => handleDisconnect(socket, userUUID));
});
// io.on을 사용하면 'connection'이 발생할 때 까지
// 소켓 객체가 대기하겠다는 의미
};
export default registerHandler;
addUser와 socket.on('disconnect', 생략) 사이가 현재는 유저가 접속한 이후 입니다.
그럼 이곳에 함수로해서 stage와 관련된 기능을 처리해줍시다.
handlers/helper.js에
const handleConnection = (socket, uuid) => {
console.log(`New user connected ${uuid}`);
};
export { handleDisconnect, handleConnection };
을 추가시켜 줍니다.
그리고,
handlers/register.handler.js도
import { handleDisconnect, handleConnection } from './helper.js';
handleConnection을 추가해주고,
const registerHandler = (io) => {
io.on('connection', (socket) => {
// 최초 커넥션을 맺은 이후 발생하는 각종 이벤트를 처리하는 곳
const userUUID = uuid;
// v4 메서드를 바탕으로 uuid를 생성 및 담아준다.
addUser({ uuid: userUUID, socketId: socket.id });
// socketId는 socket.id로 받아온다.
//이 시점이 현재 유저가 막 접속을 했을 시점 입니다.
handleConnection(socket, userUUID);
//접속 해제시 이벤트
socket.on('disconnect', (socket) => handleDisconnect(socket, userUUID));
});
// io.on을 사용하면 'connection'이 발생할 때 까지
// 소켓 객체가 대기하겠다는 의미
};
handleConnection(socket, userUUID)를 addUser와 socket.on 사이에 추가해줍니다.
handlers/helper.js에 돌아와
handleConnection함수를
const handleConnection = (socket, uuid) => {
console.log(`New user connected ${uuid} with socket Id ${socket.id}`);
console.log('Current users : ', getUser());
const {stages} = getGameAssets();
// stages 배열에서 0번 째 = 첫 번째 스테이지
setStage(uuid, stages.data[0].id);
console.log('Stage : ' + getStage(uuid));
socket.emit('connection', { uuid });
//소켓을 가지고 있는 유저 본인에게 정보를 보내줍니다.
};
위와 같이 바꿔줍니다.
getGameAssets()로 (일부 내용들 가져옴)
const [stages, items, itemsUnlocks] = await Promise.all([
readFileAsync('stage.json'),
readFileAsync('item.json'),
readFileAsync('item_unlock.json'),
]);
// readFileAsync로 assets 폴더 안 .json파일
// 을 읽어오고, 배열에 값을 저장해줍니다.
// 파일 이름을 따로 관리하는 방식으로
// 하드 코딩을 안 하는 방법도 있다.
gameAssets = { stages, items, itemsUnlocks };
const getGameAssets = () => {
return gameAssets;
};
위의 내용들을 바탕으로 가져온 Game의 핵심 Assets 정보들을 담고 있는 배열인
gameAssets를 getGameAssets함수로 return해줍니다.
그 결과 handlers/helper.js의 handleConnection 함수 내부에서
const { stage } = getGameAssets();
setStage(uuid, stages.data[0].id)
stages의 0번 째 → 첫 스테이지 id와 uuid(uer unique id)
가 setStage로 전달 돼
// 유저에게 제공할 스테이지
const setStage = (uuid, id) => {
return stages[uuid].push({id});
};
첫 번째로 이동하게 됩니다.
그 후,
socket.emit('connection', { uuid });
//소켓을 가지고 있는 유저 본인의 정보를 보내줍니다.
유저의 소켓으로 유저 본인의 정보를 보내줍니다.