이번 프로젝트에서는 2가지의 기능을 핵심으로 설정을 했다.
1. 실시간 채팅(+ 귓속말)
2. 압축된 파일 풀어 리스트 만들기(+ 편집)
우선은 실시간 채팅에 대해서 자세히 블로깅을 시작하겠다!
node
의 express
를 기본으로 사용을 하였다.
app.js
에서 등록을 하여 설정을 해주어야 하는데, 나는 이것을 따로 socket.js
파일로 빼내어 정리를 한다음 app.js
에서 다시 require해주었다.
module.exports
를 통해 외부에서 require
로 리턴 할 수 있게 해주었다.
socket
의 연결은 connection
으로 연결을 해주었고, 연결이 됐을때(connection
)와 연결이 해제되었을때(disconnect
) 구분해줄 ip
를 선언하고 이용하였다.
새로운 접속 ::ffff:172.17.0.1 zRomb4oZ26jTwQd5AAAB
클라이언트 접속 해제 ::ffff:172.17.0.1 zRomb4oZ26jTwQd5AAAB
나머지 기능은 채팅의 BackEnd에서 자세히 설명
회색 부분은 나머지 설정이라 볼 필요는 없다.
const main
을 보면 redis
로 선언된 server
를 우리가 설정한 socket.js
에서 불러와 연결을 해주었다.
이럼으로 서버에서는 socket
을 통해 이용할 수 있게 되었다.
mongodb
는 noSQL
이지만, 그래도 스키마 형태로 가공해주는 것이 편리하기 떄문에 스키마 설정을 해주었다. (mongoose
사용)
채팅에서 공통적으로 필요한 것들은 다음과 같다.
보낸 사람, 메세지 내용, 메세지 날짜(날짜는 db에서 필수적이다.)
그리고 귓속말 기능에서는 추가적으로 받는 사람이 필요하기에 이것을 구분해줄 타입(귓속말인지 아닌지)으로 나누어 구축을 해주었다.
필수적으로 필요한 것들은 require
을 true
로 설정했다. 그리고 createAt
은 지금 등록된 날짜를, type
은 기본적으로 전체 채팅을 뜻하는 public
으로 설정하였다.
user
는 이미 만들어둔 것으로 ref
를 통해 참조 할 수 있도록 했다.
socket
으로 현재 socket
을 사용할 주소를 입력하여 선언한다.
componenteDidMount()
에는 mount
됐을때 실행되어야 할 것들을 선언해준다.
joinChat
으로 socket
의 유저리스트에 등록을 시킨다.getUserList
를 통해 새로운 유저가 들어왔을때 userList를 업데이트 해준다.보여지는 페이지는 총 3부분으로 나눌 수 있다.
logs
를 통해 지난 메세지들을 받아오면 map
을 통해 MessageBox
라는 Component
를 돌려준다.
내가 보낸 것인지, 상대방이 보낸 것인지, 귓속말인지에 따라 CSS
설정을 다르게 하여 잘 구분될 수 있게 하였다.
내가 보낸 메세지는 오른쪽 정렬로 아이디 없이 표시하였다.
다른 유저가 보낸 메세지들은 왼쪽 정렬을 했다.
청록색은 귓속말로 어떤 유저에게 보내는지 보여진다.
위에서는 codesign이 code에게 보내는 귓속말이다.
일반 채팅의 경우 하얀색 바탕으로 받게 된다.
componentDidMount()
가 실행이 되면서 userList
를 받아오게 되는데 이것이 접속해 있는 유저들의 리스트이다. 이것을 통해 귓속말 할 상대를 정할 수 있게 된다.
마찬가지로 map
을 통해 리스트를 만들었고, 해당 리스트의 유저를 클릭하면 해당 유저에게 메세지를 보낼 수 있게 된다. 동시에 state
의 type
, toUser
가 바뀌게 된다. 물론, 자기 자신을 선택할 수는 없다.
기본적으로 bootstrap
으로 디자인을 하였고, onChange
를 통해 state
의 message
를 바로 변경 가능하게 하였다.
버튼을 누르면 해당 메세지가 귓속말인지 아닌지, 비어있는지 아닌지 등을 확인하여 백엔드와 통신하게 되고 잘 통신이 되었다면 socket
을 통해 전체 메세지를 전달하게 되고, 해당 state
들을 초기화해준다.
새로운 유저가 접속을 하게 되면 socket.join
을 통해 등록을 시키고,
userList
에 추가하게 된다. 그리고 업데이트된 userList
를 전체 socket
으로 보내어 받게 된다.
채팅은 전체 채팅과 귓속말이 나누어져 있는데, 한 socket
의 기능에서 처리하게 하였다. 전달받은 object의 toUser
가 있다면 귓속말이므로 해당 소켓의 아이디를 가진 사람에게만 전달하기 위해 io.to(받을사람 id).emit()
으로 처리하였다.
만약 접속을 해지하게 된다면 splice
내부 함수를 사용하여 해당 유저를 제외하게 했다.
처음 페이지에 들어와 실행하게 되는 /init
에서는 모든 채팅을 찾게 된다.
해당 함수인 findAllChats
는 접속한 유저의 아이디를 통해 DB를 다음과 같은 조건으로 조회하게 된다.
toUser
가 없는 채팅들toUser
가 접속한 유저인 것 (귓속말 받은 상대가 해당 유저)user
가 접속한 유저인 것 (귓속말 보낸 사람이 해당 유저)이렇게 되면 다른 사람에게 보낸/받은 메세지들을 제외하고 조회하게 된다.
메세지를 보내는 기능들 담당하는 이 API는 addChat
함수를 실행한다.
해당 함수는 전체 채팅인지 귓속말인지를 판단 후 넘겨 받은 Object를 DB에 저장시킨다.
안녕하세요! 백엔드 노드개발자를 목표로해서 공부중인 초보개발자입니다! 저도 채팅방을 구현하고 싶어서 자료들을 조사중인데 code_sign님의 채팅방 코드가 잘 짜여있는 것 같아 참고를 하고 싶은데 혹시 있다면, 깃헙 주소를 공유 가능하실 지 문의드립니다!!