Skip to content

tachyon83/chatting2

Repository files navigation

채팅 프로그램

배포사이트: https://chitchat-chitchat.herokuapp.com/

소개

본 프로젝트는 2인 미니프로젝트이며,
처음에는 ramgabi님과 함께하다가 그 분이 개인사정으로 빠지시고,
Danakim21님이 대신하여 프론트를 이어받아 진행하였습니다.

본 프로젝트의 기획 및 설계에 사용한 문서 링크입니다
https://www.notion.so/Chatting-Web-Mini-Project-b2105f72f1a543779e018ca617f27bd9

백엔드는 제가 맡았고,
프론트엔드는 (ramgabi님과) danakim21님이 맡았습니다.
https://github.com/ramgabi
https://github.com/danakim21

본 Readme에는 백엔드 코드와 관련된 내용만 담겨있습니다.
백엔드: https://github.com/tachyon83/chatting2
프론트엔드: https://github.com/danakim21/messaging-app
배포사이트: https://chitchat-chitchat.herokuapp.com/

개요

회원가입, 로그인 등의 기본 사용자 인증을 passport로 구현하였습니다.
로그인한 유저에 한해 소켓 연결을 시도하며, 세션 정보를 미들웨어를 통해 소켓에 붙여줍니다. (많이 고민한 부분)
소켓 연결시 현재 다른 곳에서 로그인이 되어있다면, 로그인이 불가합니다.
로그인 이후에 socket.io를 통해 소켓이 연결되고,
채팅방과 사용자 리스트를 받습니다.
채팅방 입장, 그룹 가입, 채팅방 개설, 채팅, 그룹채팅, 귓속말 등의 기능이 있습니다.
채팅방 정보, 유저 정보 변경 등의 기능도 있습니다.

Restful한 api를 만들고자 하여 경로명만으로 무엇에 관련한 요청인지 그리고 method를 통해 어떤 기능인지
파악할 수 있도록 하였습니다. 회원가입과 회원 로그인만 http요청을 통해 수행됩니다.
나머지는 모두 소켓 이벤트를 통해 관리합니다.
router에서는 경로를 분기해주는 역할만 하고
controller를 따로 두어, 데이터베이스 연결, 로직 구현 등의 역할을 수행하도록 하였습니다.

데이터베이스 연결, 모듈화, 라우팅, 컨트롤러 구현, Promise체인 활용, CRUD구현, 클라우드에 배포까지를 목표했습니다.

사용 기술 및 주요 모듈

Node Express Passport Mysql Redis Socket.io

폴더 구조

링크된 노션 페이지 참조 부탁드립니다.

주요 내용

  • 백엔드와 프론트엔드가 서로 다른 주소를 통해 배포 (CORS이슈 관리함)
  • 헤로쿠에 프록시가 있기 때문에, 백엔드에서 프록시를 신뢰(proxy: true)하여야 프론트에서 넘어오는 세션쿠키를 받을 수 있다.
  • 그래야 로그인한 세션이 소켓을 연결할 때, 그 소켓에 세션 정보를 붙여줄 수 있다.
  • 데이터베이스 접속시 connection을 계속 만들지 않고, pool을 활용하여 connection사용 후 반납하는 방식
  • 하나의 파일에서 pool을 만들고 다른 곳에서는 그 pool을 참조하는 방식
  • userDao클래스를 분할하여 쿼리 관련 메서드를 모아둠
  • roomDto, chatDto 등의 형식을 고정하여, 소켓 이벤트 처리시에 항상 같은 형식의 데이터 패킷을 주고 받도록 함.
  • eventEmitter를 사용하여 온라인 사용자 리스트 또는 현재 열려있는 채팅방 목록 등에 변경이 생겼을 시, 계속 전송하도록 함.
  • resCode라는 것을 따로 두어, 약속된 서버 상태코드를 전달하도록 함. (서버 status코드와 유사한 기능)
  • 소켓 이벤트를 io이벤트와 socket이벤트로 분리하여 관리함.
  • 소켓 이벤트를 주제별로 분할하여 모듈화함.
  • dataMap이라는 것을 두어 레디스에서 사용하는 일종의 '테이블명'을 저장해둠.
  • 소켓은 로그인 후에 연결될 수 있도록 관리함.
  • Routes를 주제에 따라 분할하여 관리
  • jwt를 활용하여 서버가 가벼워짐. 메모리나 데이터베이스를 활용하여 세션을 저장하지 않음.
  • Promise체인을 적극 활용하여, 로직을 단계별로 나누고 유지보수가 편리하도록 함. 직관성도 좋아짐
  • 동일 브라우저에서 다른 탭을 열어서 로그인 시도할 때 실패하도록 처리함. (세션 관리)
  • 다른 브라우저에서 이미 로그인된 아이디로 로그인 시도할 때 실패하도록 처리함. (로그인 유저 map관리)

어려웠거나 배운 점 그리고 보완할 점

  • 전체적으로 초심자의 구현이라 만족스럽지 않은 부분도 있고, 경험자분들의 노하우가 궁금한 경우가 있었음.
  • 프록시의 존재를 알지 못하여 소켓연결 시, 프론트에서 보내주는 세션쿠키를 백엔드가 받지 못한 문제가 있었음.(백엔드 프록시 관련 설정을 통해 해결)
  • 채팅방이 닫힐 때 수행하는 여러가지 로직이 깔끔하지 않은 것 같은 느낌임.
  • 로그아웃 또는 클라이언트에서 창이 닫혔을 때에 대한 처리 등에 관한 로직도 깔끔하지 않은 느낌임.
  • 소켓과 세션이 공유되도록 하는 개념이 처음에는 어려웠음. (코드로는 간단히 구현함)
  • 소켓 관련 이벤트를 모듈화하는 방법을 많이 고민함. (결과적으로는 간단히 구현됨)
  • 과거 채팅 내역 처리가 어려웠음.
  • jwt 리프레시 토큰을 활용하지 않아 보안 관련 문제를 완벽히 관리하지 못함.
  • CORS 이슈 관리가 힘들었음. POST, PUT등의 메서드로 요청이 있을 때 OPTIONS라는 method로 '사전요청'이 있다는 사실을 알게 됨.
  • CORS 세팅을 통해 허가할 요청 경로를 명시하여 넣어둘 수 있다는 사실을 알게 됨 (배열도 가능). 현재는 간단하게 true로 되어있음.
  • 크롬 브라우저 정책으로 도메인이 다른 곳에서 보내주는 쿠키는 거부한다는 사실을 알게 됨. <- 이를 해결하기 위해 관련 설정 필요하였음. (cookie-sameSite, cors-credentials 등등)
  • heroku에서 proxy를 앞에 세우기에 관련 설정이 필요하였음.
  • 하나의 파일에 모든 것을 넣지 않고, 여러 개의 파일로 분할하는 과정에서 비동기처리의 동기화가 어려웠고,
    공용자원을 한 곳에서만 정의하고 같이 쓰도록 하는 부분도 어려웠음.
    예시: createPool이 비동기 처리인데 그것이 완료된 후에 다른 파일에서 참조하도록 만드는 부분
  • promise체인 활용시 resolve를 통해 단 하나의 변수(또는 객체)만 전달할 수 있다는 점이 아쉬웠음.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published