ETC

[토이프로젝트] NuxtJS로 채팅 사이트 만들기

SongMinu 2022. 7. 22. 18:40
728x90

작업한 깃 주소

https://github.com/smw0807/nuxt_chatting_room

 

GitHub - smw0807/nuxt_chatting_room: vue2 기반 nuxt와 socket.io nuxt-socket-io를 이용한 채팅방

vue2 기반 nuxt와 socket.io nuxt-socket-io를 이용한 채팅방. Contribute to smw0807/nuxt_chatting_room development by creating an account on GitHub.

github.com

 

개인적으로 모르는거나 새로운걸 습득하기 위해 보다보면 한 번에 이해가 되는 것들이 있고, 한 번에 안돼서 몇 번 더 보면 이해가 되는 것들도 있는 데 종종 이상하게 아무리 몇 번을 봐도 이해가 안 되는 것들이 있다.

그런건 일단 링크 같은 걸 따로 저장해 두고 한참 뒤에 다시 보면 갑자기 이해가 되는 경우가 많았다.

그중 하나가 웹소켓이었다.

만든 이유와 작업 목표, 다짐

Node.JS 교과서 개정 2판 책을 사놓고 주말마다 조금씩 보고 있었다.

읽던 중 express를 이용해 웹을 만드는 것 중에 Socket.IO를 이용해 채팅방을 만드는 예제가 있길래 설명을 보면서 하나하나 따라 쳐보고, 뭔가 설명이 부족한 것 같다 싶은 부분은 구글링을 해서 추가적으로 더 보다 보니 드디어 좀 이해가 됐다.

 

이걸로 끝내기엔 머리에 오래 남지않을 것 같았고, 한창 공부하다가 무언가 제대로 된 프로젝트를 만든 적이 없는 Vue를 이용해 만들어보자! 하는 생각으로 시작했다.

 

우선 Vue3는 아직 공부 단계여서 자신이 없어 Vue2를 사용하기로 했고, NuxtJS가 개인적으로 편하기도 해서 Nuxt 쓰기로 했다.

시작 전 제일 중요하게 생각한건 다른 사람들이 vue를 이용해 만든 채팅 소스는 절대 보지 않고, 소켓 관련 부분은 책에 본 express와 socket.io 예제만 참고하고 그 외에 부분은 모두 내가 생각하는 방법으로만 구현하기로 했다.

중간에 소켓 관련해서 도저히 모르겠는 건 구글링했고 vuetify 컴포넌트는 공식 홈페이지 참고하면서 작업했다.

 

그리고 토이프로젝트이기 때문에 가능한 2달 이상은 시간을 투자하지 말자는 마인드로 시작했다.

기능도 책 예제 처럼 단순하게 만들자는 생각으로 시작했기에 솔직히 한 달 안에 끝날 거라 생각했으나... 

하다 보니 자꾸 욕심이 생겨 계획에 없던 기능들이 하나 둘 추가되다 보니 시간이 길어져 약 2달 좀 안되게 작업이 끝났다.

기술 스택

Front

NuxtJS, VuetifyJS

nuxt-socket-io

Back

Express, MongoDB(mongoose)

socket.io. jwt

몽고디비는 MongoDB Atlas를 사용했다.

구현 기능

  1. 회원가입
  2. 로그인
  3. 사용자 정보 수정
  4. 생성된 채팅방 리스트
  5. 채팅방 생성
    일반방 또는 비밀번호 방
  6. 채팅방 접속
    - 일반방 접속은 바로 접속
    - 비밀번호방 접속은 패스워드 입력 후 접속
  7. 채팅방 접속자 리스트 표기
  8. 채팅방 입장, 퇴장 시 시스템 문구
  9. 채팅방 메시지 입력, 전달

원래 최초 목표는 로그인 기능도 없이 그냥 세션만 써서 웹 접속하면 세션 받고, 방 만들고 채팅만 주고받고 였다.

그럼 4, 5, 6, 9 이렇게인데

그래도 기왕 하는거 회원 기능도 넣고, 세션 말고 jwt를 쓰고, jwt를 썼으니깐 토큰 검증도 넣고, 방에 누구 있는지는 보여주자...등등 하다보니

기능이 늘어버렸고 작업 시간도 늘었다.

특히 7번이 유난히 작업이 오래 걸렸다.

 

구현된 모습과 주요 소스

회원가입
로그인
로그인 했을 때 사용자 정보 (클릭시 출력)
사용자 정보 수정
채팅방 생성
백단 방 생성 처리하는 소스

방이 생성되면 웹에 방 리스트를 다시 조회하라고 보낸다.

그럼 방 리스트 화면에서 대기중인 사람들은 아래처럼 생성된 방을 실시간으로 볼 수 있다.

채팅방 리스트

자물쇠 있는 방은 비밀번호를 입력해야 들어갈 수 있다.

비밀번호 방 입장 시
방 접속 시

방을 만들면 바로 방으로 접속되고, 그 이후에 접속하는 사람들은 입장했다는 문구와 함께 접속자 리스트에 표기가 된다.

방 입장 요청
join 처리 로직

join 요청하면서 사용자 정보와 접속하는 방 아이디를 넘기면, 소켓 서버에서 해당 방으로 소켓을 조인시키고 입장했다는 문구를 웹으로 보낸다.

퇴장 시

누군가 나가면 퇴장 문구가 출력된다.

웹단 방 나가기 버튼 함수 소스
소켓서버 소스

방에서 나가면 해당 방에 남아 있는 인원을 파악하고 아무도 없으면 방을 삭제시킨다.

있으면 퇴장했다는 메세지를 보낸다.

채팅 모습

대략 이런 모습이다.

채팅창도 처음엔 메세지만 딱 보내려고 했지만 사용자 프로필도 추가했고 여러 명이 있는데 구분할 수 있게 해줘야지 않을까? 해서 위와 같은 모습이 됐다.

솔직히 별거 아닌 기능들인데 참 많은 시간도 소비했고, 아직 부족하다는 생각도 많이 들기도 했다.

다만 욕심으로 기능들 추가하다 파일 첨부 같은 기능은 포기한 게 좀 아쉽긴 한데

여기에 너무 많은 시간을 소비하는 건 좀 그래서 기약 없는 나중을 위해 남겨두는 걸로...

 

시간이 많이 소모된 부분

작업하면서 시간이 많이 소모된 부분들이 몇 가지 있다.

 

첫 번째는 프론트 백엔드 분리

이게 처음엔 간단하게 만들 생각이라 Nuxt안에 그냥 express를 합쳐서 만드려고 했다. (간단한 기능들 뿐이라..)

하지만 소켓을 연결하는데 문제가 좀 있었고

이렇게 Nuxt 안에서 express 라우터 부분에 저렇게 소켓을 가져오는 방법을 아무리 생각해도 모르겠어서 분리하기로 결정했다.

그리고 Nuxt 안에서 express를 사용하면 저렇게 사용할 수 있게 담는 방법도 떠오르지 않았다.

덕분에 분리 작업하는 시간이 좀 걸렸다.

그냥 처음부터 분리했어야 했는데...

 

두 번째는 생성된 방으로 접속

이건 책 예제가 있는데 오래 걸린 게... 책은 epxress 하나로 view 파일 렌더도 해주고, api 처리도 하고 socket도 처리해줘서 가능했던 건지 모르겠는데, 난 웹은 nuxt로 따로 돌리고 서버는 epxress로 따로 돌리니깐 책 예제로는 작동 안 하는 부분이 많았다.

그래서 이 부분은 도저히 모르겠어서 구글링도 많이 하고 코딩 박치기도 신나게 한 덕분에 머릿속에 제대로 각인은 됐다고 생각한다.

특히 위에 사진처럼 adapter도 예제 보면서 쳐도 이해가 잘 안 되는 부분이었는데 도움이 많이 됐다.

이것처럼 소켓을 생성하고 app에 담아서 다른 곳에서 꺼내 쓸 수 있다는 게 참 신기했다.

웹소켓을 제대로 써본 적이 없어 이번에 처음 알았다.

 

세 번째는 현재 접속자 표기

처음에는 방을 만든 사람이 새로운 접속자가 들어오면 그 정보를 합쳐서 들어온 사람들에게 접속자들 정보를 넘기는 쪽으로 생각하고 만들었었다.

하지만, 그 방식이 마음에 안들었던 건지 뭐가 문제가 있었던 건지 기억이 안나는데 바꿨다.

아무튼 이 기능을 만드는데 정말 많은 시간을 사용했다.

내 머리로는 돼야 하는 게 맞는 것 같은데 안돼서 로직 수정을 참 많이 했다.

기억나는 문제 1개는 이렇게 방 접속 처리를 한 후에 socket.join 아래에 사용자 정보를 담아두고 웹으로 던져 주면 될 것 같았지만 안됐었고,

결국 생각해낸 건 글로벌 변수였다.

server/index.js

이렇게 그냥 맵을 글로벌 변수로 만든 다음 방으로 접속하는 로직이 끝나면 맵에다 키로 방 아이디를 넣고, 값으로 사용자 정보를 넣어준 다음 그 정보를 웹으로 보내게 해줬다.

아마 보통은 이런 경우는 레디스를 설치해서 사용하는 걸로 알고 있는데.

그렇게까지 하기엔 또 작업량이 늘 것 같아서 이렇게 대체했다.

 

이 정도인 것 같고 그 외에는 크게 오래 걸린 작업은 없는 것 같다.

 

마치며

6월 8일 첫 레파지토리를 만들었고,

6월 9일 Nuxt 웹 소스를 추가하고, 13일부터 작업을 시작한 것 같다.

그리고 어제인 7월 21일 프로젝트를 마무리하기로 했다.

 

처음 목표는 간단한 프로젝트였는데

작업하다 보니 즉흥으로 기능들이 추가되면서 커진 탓에 설계도 없고, 중구난방 한 작업 순서로 인해 솔직히 만족스러운 프로젝트는 아니다.

특히 가볍게 시작해서 제대로 된 설계 없이 진행한 게 가장 아쉽다.

 

웹단도 최대한 컴포넌트의 장점을 활용해 만들어 보자였는 데, 이게 잘 됐는지는 모르겠다.

프론트, 백 쪽 로직 부분들도 중간중간 꼬인 로직들도 많아서 최대한 수정하긴 했지만 뭔가 더 잘 짤 수 있었을 것 같은데 하는 아쉬움이 많다.

그래도 만들어진 웹 화면만 보면 내가 구현하고자 했던 기능들이 하나하나 만들어져서 뿌듯하긴 했다.

 

반응형