2024-12-19 TIL
1. 이번 프로젝트 트러블슈팅
프로젝트 개요
이번 프로젝트는 웹소캣을 어떻게 사용하면 좋을까 연습하는 시간이었다.
제공된 코드를 수정하여 서버와 클라이언트를 만들고 다량의 접속을 관리하면서 랭킹 점수가 갱신되면 해당 점수를 브로드캐스트로 보내는 방식을 취하고 있다.
소켓 통신은 node.js의 socket.io 모듈을 사용하고 있다. express를 통해 서버를 연결시킨 다음 socket을 하나 만들어 그 소켓을 통해 통신을 관리하고 있다. 이번에는 웹게임을 구동시키는 것이라 별도의 REST API 통신은 사용하지 않고 직접 on, emit을 관리하고 있다.
문제 리스트
- 파일이 분할되면서 어떤 파일을 손대면 좋을지를 찾기가 어렵다.
웹 서버를 담당하는 파일을 src에 넣어두고 클라이언트를 담당할 파일을 clientFile 폴더 안에 넣는 식으로 관리를 하긴 했지만 파일이 많아지면서 파일 간의 연결을 어떻게 하면 좋을까 눈에 들어오지 않는 문제가 있었다. readme를 통해 해당 파일들이 무엇을 기능하는지 적기도 했지만 언제 socket을 호출하는지를 찾다가 시간을 많이 잡아먹기도 했다.
=> 해당 문제를 해결하기 위해선 단순히 파일 내에 무슨 기능이 있는지만 적지 말고, 파일 내의 어떤 함수가 존재하며 각 함수가 어떤 식으로 함수를 받아오는지까지 적을 수 있도록 해야겠다. - ES2에 배포하면서 생기는 문제
지금까지 프로그램을 실행하던 환경은 localhost에서 받아왔고, 클라이언트에서 값을 받는 것도 그걸 기반으로 작성되어 있었다. 그러나 ES2 등 배포를 하게 되면 서버의 IP 값, 또는 그 IP값을 기반으로 하는 DNS 주소를 읽도록 바꿔야 한다.
const socket = io('localhost:3000', { //해당 부분의 값을 받아올 ip 값이나 dns 값으로 바꿔줘야 한다는 의미.
query: {
clientVersion: CLIENT_VERSION,
},
});
- 브로드캐스팅 하는 방법
현재 프로젝트에선 브로드캐스팅을 하는 타이밍을 크게 2번 잡았다. 하나는 스테이지가 넘어가면서 해당 유저의 점수가 가장 높은 점수인지 확인하여 브로드캐스팅 호출하는 것, 다른 하나는 게임이 끝난 다음 다시 시작할 때 보내는 것이다. 너무 많이 브로드캐스팅을 하는 것도 보기 좋지 않아 보이기도 하는 점 때문에 나중에 변경할 수 있는지 검토해 보도록 한다.
- redis 연결 과정
redis는 일종의 object 데이터 리스트처럼 쓸 수 있는 noSql 데이터 베이스 같은 것이다. key, value 방식으로 데이터를 저장하고 key를 입력하면 데이터를 받을 수 있다는 점은 영락없이 map이나 object,dict과 같은 방식이다.
해당 기능을 이용하기 위해서 먼저 직접 redis 로컬을 설치를 고려하였다. redis는 원래 리눅스에서 사용하는 걸 상정하고 만들어졌기 때문에 현재 컴퓨터의 운영체제인 window에선 작동이 어려울 수 있다는 문제를 듣게 되었다.
그래서 직접 설치는 하지 않고 docker를 이용해 이미지(이미지 파일 같은 게 아니라 docker 내부에서 사용할 수 있는 공용 도구 같은 것)로 만드는 작업을 해보려 했다.
docker를 설치하고 desktop으로 불러 오려 하자 오류가 발생했다. 처음엔 설치 중의 오류거나 docker 또한 운영체제를 가리나 고민했으나, 오류 코드를 보니 WSL을 새로 업데이트 하라는 문구였다.
- 계속하려면 Linux용 Windows 하위 시스템 최신 버전으로 업데이트해야 합니다. ‘wsl.exe –update’를 실행하여 업데이트할 수 있습니다.
해결 방법으로 powershell을 관리자 권한으로 실행하여 wsl –update를 실행하여 버전을 맞추기도 했고
제어판 => 프로그램 => 프로그램 및 기능 => windows 기능 켜기/끄기 에 들어가
- Linux용 window 하위 프로그램
- 가상 머신 플랫폼
- Hyper - v
등을 켜보기도 했다. 일단 작동 자체는 되는 모양으로, 리눅스를 윈도우에서 설정하는 과정에서 문제가 생긴 모양이다.
그러나 실행하고 난 뒤 컴퓨터 자체 메모리가 너무 부족하단 사실을 알게 되었다.(다른 파일 같은 걸 켜면 랜더링이 한 10초 정도 뒤에 되는 현상, 폴더 안이 검게 차 있는 현상).그래서 도커를 사용하는 것은 포기하고 redis cloud를 사용할 방법을 찾았다.
이 쪽은 훨씬 간편하여, 글로벌하게 redis 모듈과 함께 redis-cli 라는 모듈을 같이 받았다. (단 이쪽 모듈은 글로벌하게 선언해야 작동했다.)npm install -g redis-cli
작업을 하고 서버를 연결하는 것처럼 클라이언트 선언, 연결하자 이제서야 연결이 되었다. ```js import redis from ‘redis’ import dotenv from ‘dotenv’ import express from ‘express’ import { json } from ‘stream/consumers’;
dotenv.config();
export let redisClient = null; export let redisCli = null;
export const ConnectToRedis = async () =>{ redisClient = redis.createClient({ url:
redis://default:${process.env.PASSWORD}@${process.env.ENDPOINT}:${process.env.PORTNUMBER}/0
, legacyMode: true // 반드시 설정? });redisClient.on(‘connect’, ()=> { console.info(‘Redis Connected’); })
redisClient.on(‘error’, (err) => { console.error(‘redis error’, err); })
//CRUD
redisClient.connect().then();//redis v4 비동기 연결 redisCli = redisClient.v4; console.log(“REDIS연결 확인”) }
export const SetValueFromRedis = async (key) => { console.log(“redis입력 확인”) let value = await redisCli.get(key); value = JSON.parse(value);
return value; } ```
- 계속하려면 Linux용 Windows 하위 시스템 최신 버전으로 업데이트해야 합니다. ‘wsl.exe –update’를 실행하여 업데이트할 수 있습니다.
예상 질문 및 답변
- 브로드캐스팅 하는 타이밍을 스테이지 넘어갈 때와 게임 오버가 될 때 한다고 했는데 다른 때에는 언제 하면 좋을까.
- 가장 좋은 방법은 일정 스테이지를 넘어간 이후부터 일정 간격마다(예상하기론 10초 간격) highscore를 갱신하는 방버이 있습니다. 다만 해당 방법은 그 만큼 많은 트래픽이 발생하여 컴퓨터 성능을 고려하여 현재 방법을 사용하게 되었습니다.
- 파일 정보에 대해 세분화시켜 정리한다면 구체적으로 어떻게 정리한다는 의미인가.
-
- ES2를 통해 배포할 때 socket에서 접속하는 ip 주소는 어떤 식으로 설정하고 있는가.
- 작업하고 있는 파일에 직접 ip 주소를 입력하여 수정하는 정적 라우팅 방식을 사용하고 있습니다.
- 현재 방식은 redisClient, redisCli를 export를 써서 내보내고 있다. 해당 방식 말고 다른 방식으로 보낼 수 있는가?
- redis cloud를 사용하기 위해선 먼저 서버에 연결할 필요가 있지만, 별도의 함수에 넣지 않을 경우 해당 파일을 import 할 때마다 다시 연결이 되는 문제가 있습니다. 그래서 현재처럼 함수로 묶어 놓은 상태이다. 좀 더 개선한다면 class를 만든 다음에 그 안에 다른 함수나 기능을 집어 넣는 방식을 할 수 있도록 개선해 볼 수 있을 것 같습니다.
- docker에 대해서 설명해 보시오.
- redis 처럼 window를 지원하지 않는 기능을 사용하기 위한 툴이며, 가상 머신 중 hpyer - v를 기반으로 하고 있습니다. docker에는 각각 운영체제가 작동할 환경인 컨테이너, 컨테이너들 내부에서 실행할 수 있는 범용 함수나 기능 등을 이미지라고 합니다.