프로젝트 소개
열줌쉬어는 학습자를 위한 웹 서비스로 스탑워치/타이머 기능을 통해 실시간으로 공부시간을 기록하고, 가입한 그룹 내에 공부량을 시각화하여 보여주는 웹 사이트 입니다.
개발 기간
23. 10. 23 ~ 23. 11. 10 (약 2주)
사실 진행중
개발 환경
Language, Framework - Javascript, React
DataBase - MySQL, MongoDB
Devops - AWS EC2, AWS RDS, Nginx
기술 스택
프론트 엔드 - 2명
- Vite
- ReactJS
- JavaScript
- Redux-Toolkit
- TailwindCSS
- Socket.IO- client
백엔드 - 3명
- Express
- Mongoose
- Sequelize
- JWT (jsonwebtoken)
- Socket.IO
- MongoDB, AWS EC2, NGINX
협업 툴
- 노션
- 깃허브
- Zoom
- Slack
백엔드 기술 스택 선택 이유
MongoDB 편
고백합니다,,,, !!!
사실,, 처음 계획은 관계가 필요한 데이터는 RDS에 저장하고 실시간 통신 부분인 채팅과 타이머쪽 데이터는 몽고디비에 저장하려고 했었습니다,,
동일한 데이터를 가지고 CRUD를 수행할때 MySQL에 비해 MongoDB가 더 빠르게 결과가 나온다고 알고있었기 때문입니다. 사실 대용량의 데이터를 빠르게 처리한다고 MongoDB를 사용한다곤 하지만 저희의 작고 귀여운 (하지만 멋진) 프로젝트는 대용량의 데이터는 겪어보지 못한 친구라 빠르게 처리하는지는 감이 안왔지만, MySQL에 비해 초반 db설계가 빠르다는 것은 몸소 느꼈습니다.
하지만, 우리 프로젝트의 채팅은 그룹별로 채팅방이 있는 단체채팅이었기 때문에 그룹정보를 가져와야했고 그룹 데이터를 RDS에서 가져와서 몽고디비에 동기화 시키려 하였으나 동기화를 시키는 시점과 중간에 그룹의 정보가 수정된다면 ,,등등 경우의 수를 모두 보고 온 결과 계획한 프로젝트 기간안에 할 수 없을 것같다 라는 결론과 모두가 실시간 통신은 미지의 영역(?)이었기 때문에 과감히 몽고디비 일인체제로 떠나게되었습니다..
하지만 현재는 리팩토링을 진행하며 다시 RDS와 MongoDB 두 데이터베이스를 역할에 따라 나누어 사용하고 있답니다^^* 하하
Socket.IO 편
실시간 채팅 구현은 socket.io 라이브러리를 사용하여 구현했습니다. 왜 소켓을 썻느냐! 라고 물으신다면 서버에 요청을 보내는 역사속으로 들어가야 하는데 과거에는 서버로 요청을 url을 통해 주고 받았는데 여기서 조금 더 발전된 것이 Ajax통신으로 서버 XMLHttpRequest 객체로 요청을 보내면 서버가 응답을 주는 방식입니다. 새로운 페이지를 요청하는 방식이 아닌 데이터만을 요청하는 방법으로 사용자의 이벤트로부터 JavaScript는 사용자가 이벤트를 발생시킨 DOM을 읽으며 `XMLHttpRequest` 객체는 해당 DOM의 값을 읽어 서버에 넘겨주게 됩니다.
다시 서버는 문자열이나 JSON, XML 형식으로 `XMLHttpRequest` 객체에 요청 결과를 넘겨주고 JavaScript는 넘겨받은 값을 해당 DOM에 입력해줍니다.
다시 말해서 Ajax를 사용함에 따라 DOM 일부의 값만 변경할 수 있다는 장점이 생겼는데, 이 방식도 결국은 HTTP를 사용하기 때문에 요청을 보내야 응답이 전달되고 변경된 데이터를 가져오기 위해서 일정시간마다 데이터를 갱신하게 한다든지 사용자로 하여금 DOM 요소에 이벤트를 발생시키도록 유도하는 것은 자원낭비라는 것이 결론일 수 있습니다.
이러한 문제를 해결하기 위해 등장한 ‘웹소켓’ 이라는 녀석을 해당 라이브러리(socket.io)를 통해 사용했습니다.
RESTAPI
클라이언트와 서버의 상호작용을 최적화하기 위해서 HTTP를 사용하여 RESTful API를 구현했습니다.
노션을 활용하여 API 명세서를 작성했습니다.
명세서에는 각 엔드포인트, 요청 및 응답 형식, 파라미터, 성공 및 실패 시의 동작 상태코드등을 자세히 기술하여 개발팀 간의 이해를 촉진했습니다.
그외
소켓통신이냐 서버로 요청을 보내냐 그것이 문제로다
우선 이 주제로 이야기를 하려면 원래 서버의 폴더 구조를 봐야하는데 폴더구조는 이렇게 api서버와 소켓서버로 나누었습니다. (구조를 이렇게 한 이유는 서버 간 기능을 분리함으로써 성능을 향상시키고자 였는데… 더보기)
우리 프로젝트에서 채팅은 그룹별 그룹채팅인데 그룹별로 채팅방을 파려면 그룹에 속해있는 멤버도 알아야해서 User 테이블에 해당하는 닉네임의 아이디 인덱스 값과 Group 테이블의 데이터가 필요하므로 서버 디렉토리의 db데이터를 소켓서버 디렉토리로 가져와야 한다. (유저 테이블,그룹테이블-api 서버 디렉토리와 소켓서버 디렉토리)
제가 생각한 방법은 이렇습니다.
- 클라이언트에서 서버에 요청을 해서 데이터를 받은다음 그 데이터를 body 에 실어서 소켓서버에 보내주기
- 클라이언트가 어떤 페이지에오면 소켓이열리도록 하기 → 페이지접속하면서 클라이언트가 서버한테 데이터 요청→ 서버는 데이터를 클라이언트한테 전송 → 클라이언트가 응답데이터 소켓서버에 바디에 실어서 전송이었습니다.
서버 부하를 줄이기위해서 구조도 나누고 데이터베이스도 역할에 맞게 나누려고 했는데 취지에 맞지 않다는 생각이 들었고 해당 고민은 데이터베이스를 하나로 합치면서 자연스럽게 해결이 되었지만 현재 리팩토링 하는 과정에서 다시 고민해볼 문제입니다.
나의 역할
저는 group쪽의 전반적인 CRUD와 채팅기능을 구현했습니다. 그룹 기능에는 생성, 삭제, 수정, 조회뿐만 아니라 그룹 요청 및 요청 취소, 그룹장의 수락/거절 기능이 있습니다. 그리고 그룹장의 경우 그룹 삭제를 통해 그룹원 전체를 삭제하며, 일반 그룹원은 그룹 탈퇴를 통해 해당 그룹을 떠날 수 있도록 구현했습니다.
채팅 기능에서는 각 그룹당 하나의 채팅방이 생성되며, 해당 그룹의 멤버만이 채팅방에 접근할 수 있도록 설계했습니다.
해당 기능을 수행하면서 예상치 못한 상황과 시나리오에 당황했지만.. 그래도 이런 상황에서 대응해보았다는 것이 이번 프로젝트 진행하면서 좋았던 경험이었던 것 같습니다. 사실 머리가 안돌아가는 날에는 팀원분들께 넌지시 말하면서 같이 고민도 하고 제 의견에 대한 지지를 받으려 설득한 적도 있습니다. 푸하하,,
회고
이번에 진행했던 프로젝트,, 결과와 상관없이 저는 많이 배웠고 정말 좋았습니다. 모든 팀원 하나하나 어느 누구도 진행했던 프로젝트에 열심히 하지 않은 팀원이 없었습니다. 진행했던 프로젝트에 팀원 모두 욕심있기 때문에 고민도 많이했던 것 같습니다.
거의 매일 회의하며 작성한 회의록과
우리 프로젝트에서 각자 기능에 대한 회고를
모두모두 작성해주셨습니다.
사실 다들 너무 열심히라 ‘제발좀 자!!!’ 라고 한적도 많았지만,,
내가 자고있을때 누군가 열심히 한 흔적이 남아있다면 너무너무 자괴감이 들었지만….!!!
사실 좋은 기폭제가 되어 더더 열심히하려고 하게 되는 좋은 자극이 서로서로에게 되어준 것 같습니다. (‘저만 그랬을 수도 있습니다.’ ) 이런 팀원들을 현업에서도 꼭 다시 만나고싶고( ‘저만 이런 생각이 든게 아니었으면 좋겠습니다.’ ) 이런 팀원들이라면 발전했으면 했지 절대 도태되지는 않을 것같은 … 이말은 좀 그런가
암튼 ,, 앞으로도 리팩토링 열심히해서 말끔한 효자 프로젝트가 되었으면 좋겠습니다. 아자아자! (*•̀ᴗ•́*)و 완성되면 사진과 더 자세한 회고 적어보겠습니다.
'SeSAC' 카테고리의 다른 글
[SeSACXCodingOn] 웹풀스택과정 14W_02 : React hook form (4) | 2023.10.16 |
---|---|
[SeSACXCodingOn] 웹풀스택과정 14W_01 : 리액트 라우터 (4) | 2023.10.16 |
[SeSACXCodingOn] 웹풀스택과정 13W_02 : 리액트 (3) (0) | 2023.10.11 |
[SeSACXCodingOn] 웹풀스택과정 12W_03 : 리액트 (2) (0) | 2023.10.06 |