ALOA 프로젝트
로스트아크 api를 이용한 전적검색기능을 이미지화 시키는 사이트 개발
aws-ec2를 이용하여 https 웹페이지 배포
github 주소 > 홈페이지 바로가기
1. 개요
1.1 프로젝트 요약
1. 일정
2023년 10월 21일 ~ 2023년 11월 28일(39일)
2. 프로젝트 요약
- 로스트아크 api를 이용한 전적검색기능을 이미지화 시키는 사이트 개발
- bootstap과 미디어쿼리를 이용한 반응형 웹사이트개발과 테마설정기능
- react의 라이브러리를 활용한 DnD, toggle, list 기능 구현
- 상태관리와 쿠키를 통한 관리자 기능 구현
- AWS-EC2와, aws Route53를 이용한 https 웹사이트 배포
- python을 이용한 서버접속자수 로그 자동기록
3. 나의 역할
- 프로젝트 매니저로 일정 조율, git 관리
- 로스트아크 API를 사용하여 필요한 데이터 수집/가공 알고리즘 구현
- 수집한 데이터를 이미지화 시키는 알고리즘 구현
- 해당 이미지를 aws-s3에 저장하고, 가져오는 API 제작
- Python을 활용한 서버접속자수 로그 자동기록 알고리즘 구현
- 서비스에 필요한 추가기능 개발
4. 느낀점/배운점
- React에서 aws에서 지원하는 다양한 서비스를 경험해봄
- 실제 서비스를 기획/개발 하는 과정에서 사용자 경험에 대해 많이 고민해보고 개발을 진행함.
5. 개발시 발생한 문제점/해결책
- 프로젝트 초창기엔 최적화 문제를 신경을 안쓰고 있다가, 서비스 에서 문제가 생겼지만, 코드를 리펙토링하고 불필요한 부분들을 최적화 하여 LightHouse를 통해 높은 점수를 받음
- AWS-프리티어를 이용하여 서버에 사용된 EC2의 RAM이 부족했지만, 메모리 스왑을 통해 해결함
- 생성된 이미지의 용량이 너무커 서버측에서 문제가 생겼지만, 이미지 리사이징을 통해 용량을 줄여 해결함
- AWS의 과금정책이 변경되어 요금이 과하게 부과되었지만, 사용하던 서비스를 줄여 해결함
- 로스트아크 API의 빈번한 업데이트에 의해 버그가 생겼지만, 에러핸들링을 통해 해결함
2. 사용된 기술
2.1 js
- dotenv: 민감한 개인정보를 숨기는 env 파일을 사용하기 위한 모듈
2.2 app-server
- canvas2image: DOM을 jpg사진으로 변경해주는 모듈
- file-saver: 서버에서 보내주는 사진을 클라이언트쪽 컴퓨터에 저장하는 모듈
- react-copy-to-clipboard: 클라이언트에서 클립보드를 저장하는 모듈
- react-toastify: 토스트(알림) 효과를 구현하기위해 사용한 모듈
2.3 api-server
- aws-sdk: nodeJS에서 aws를 사용하기 위한 모듈
- multer: 클라이언트에서 전달한 이미지를 받기위한 모듈
2.4 python
- dotenv: Python에서 env파일에 있는 정보를 사용하기위한 모듈
- boto3: Python에서 aws-s3에있는 파일에 접근하기 위한 모듈
- subprocess: Python에서 cmd요청을 하고 log를 받아오기 위해 사용한 모듈
3. 코드 분석
Layout
import { Outlet } from "react-router-dom";
import Header from "./Header";
import Footer from "./Footer";
import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { setIsThemaOpen } from "../../store/mainSlice";
import { ToastContainer } from "react-toastify";
import { useCookies } from "react-cookie";
import { signin, signout } from "../../store/loginSlice";
function Layout() {
const isDark = useSelector((state) => state.mainSlice.isDark);
const thema = useSelector((state) => state.mainSlice.thema);
const dispatch = useDispatch();
const is_signed = useSelector((state) => state.loginSlice.is_signed);
const is_manager = useSelector((state) => state.loginSlice.is_manager);
const name = useSelector((state) => state.loginSlice.name);
// 기존 쿠키 저장
const [cookies, setCookies, removeCookies] = useCookies(["id"]);
const logOut = function () {
dispatch(signout());
removeCookies("is_signed");
removeCookies("name");
removeCookies("is_manager");
setCookies("is_signed", false, { path: "/" });
};
useEffect(() => {
if (cookies.is_signed && cookies.name) {
dispatch(
signin({
newUser: { name: cookies.name, is_manager: cookies.is_manager },
})
);
}
}, []);
useEffect(() => {
if (is_signed) {
setCookies("is_signed", true, { path: "/" });
setCookies("is_manager", is_manager, { path: "/" });
setCookies("name", name, { path: "/" });
}
}, [is_signed]);
return (
<div
className={`App ${isDark} a${thema}`}
onClick={() => {
dispatch(setIsThemaOpen({ newIsThemaOpen: true }));
}}
>
<Header logOut={logOut} />
<ToastContainer
position="top-right" // 알람 위치 지정
autoClose={6000} // 자동 off 시간
hideProgressBar={false} // 진행시간바 숨김
// closeOnClick={true} // 클릭으로 알람 닫기
rtl={false} // 알림 좌우 반전
pauseOnFocusLoss={false} // 화면을 벗어나면 알람 정지
draggable={false} // 드래그 가능
pauseOnHover // 마우스를 올리면 알람 정지
theme="light"
// limit={1} // 알람 개수 제한
/>
<Outlet />
<Footer />
</div>
);
}
export default Layout;
최상위 컴포넌트로 로그인 쿠키와 테마를 설정하고, Toast 컴포넌트를 집어넣어, 알림창을 만들어 놓는다.