초보 개발자

[ Node.js, Vue.js, Socket.io ] 카톡같은 채팅 만들기 1 본문

[ Node.js Vue.js Socket.io ] 채팅

[ Node.js, Vue.js, Socket.io ] 카톡같은 채팅 만들기 1

taehyeki 2022. 5. 15. 19:04

완성본 미리보기

2022.06.06 - [[ Node.js Vue.js Socket.io ] 채팅] - [ Node.js Vue.js Sockect.js ] 카톡 채팅 만들기 완성

 

내가 구현해보려고  하는 기능은 기본적인 채팅 기능에 더하여  여러가지가 있다.

 

1. DB를 사용하여 나갔다 들어와도 기존 채팅이 유지가 되어있어야 함 ✅

2. 읽음표시 기능(실시간) ✅

3. 카톡처럼 같은 시간에(분 단위)적히면 마지막 채팅만 시각이 적혀야함, ✅

4. 채팅방 목록에 안읽은 채팅 개수와 마지막 채팅 , 마지막 채팅 시간, 프로필 사진 받기, ✅

5. 채팅 삭제 기능, 상대방에게도 메시지가 바뀌어 보여야함 (실시간) ✅

6. 사진 및 동영상 전송 기능, ✅

7. 현재 상대방이 들어와있는지 표시할 수 있는 기능 ✅

 

위와 관련하여 인터넷에서 검색을 해보았지만 거의 대다수가 단순한 채팅기능만을 구현하여, 정보를 찾기 힘들었다..

따라서 내가 생각할 수 있는 범위에서 구현해보았다.

 

[ Node.js, Vue.js, Socket.io ] 카톡같은 채팅 만들기 1 : 채팅서버, 라우터, 소켓구조, api

[ Node.js, Vue.js, Socket.io ] 카톡같은 채팅 만들기 2 :  소켓 플러그인, 라우터 구조, 채팅방 목록,  채팅방 목록 실시간 업데이트 

[ Node.js, Vue.js, Socket.io ] 카톡같은 채팅 만들기 3 : 채팅방, 기존 채팅 불러오기, 시간 표시 생략,  채팅 입력, 읽음 안읽음 실시간 처리

[ Node.js, Vue.js, Socket.io ] 카톡같은 채팅 만들기 4 : 채팅방에서 나간 경우, 채팅 삭제

[ Node.js, Vue.js, Socket.io ] 카톡같은 채팅 만들기 5 : 현재 상대방이 접속해있는지 확인, 사진, 동영상 올리기

 

 

채팅서버

먼저 노드 서버이다. 채팅 기능밖에 없기 때문에 상당히 단순해 보인다.

app.js

채팅과 관련하여 DB에서 프로시저로 작업하기 위해 해당 라우트로 들어오면 백엔드에서 실행시켜줄 라우터 코드들이다.

 

라우터

1. 채팅 목록을 불러오는 역할 get_chat_rooms

router.js

2. 채팅 내용을 불러오는 역할 get_chats

3. 채팅을 입력했을 때 저장하는 역할 insert_chat

4. 이미지와 동영상을 보냈을 때 처리하는 역할 upload_img_to_s3, upload_video_to_s3

5. 채팅을 삭제 하였을 때 처리하는 역할 delete_chats

소켓 구조

server-side 소켓의 구조이다.

 

소켓을 생성하는 역할을 한다. 아래의 allowEI03의 역할은 잘 알지 못한다. 하지만 저 옵션을 주지 않으면 에러가 났다 ( 이거 찾는데 엄청 시간이 걸렸다.. )

app.set에 io라는 이름으로 설정해두어서 request가 오면 request안에서 io를 사용할 수 있도록 설정해두었다.

 

클라이언트의 소켓과 연결되었을 때 먼저 그 소켓의 아이디를 출력을 해준다. 

 

1. on didYouDelete

 

채팅을 삭제하였을 때 클라이언트 측에서 소켓 서버측으로 emit을 날리는 이벤트이다.

뒤에서 한번 더 설명하겠지만 A유저와 B유저가 한 채팅방에 있고, A유저가 채팅을 지웠을 경우에 상대방에게도 그 메시지가 삭제 되었다고 보여야할 것이다. 그걸 처리해주는 것이 socket.to(roomId).emit('yesDelete')이다. 또한 만약 마지막 채팅을 유저가 지웠다면 채팅방 목록에서도 삭제된 메시지 입니다 라고 보여져야할 것이다. 이걸 처리해주는 것이 socket.to(roomId).emit('yesDeleteForRoomList')이다.

 

2. on areYouInApp

 

상대방이 현재 로그인 했는지 확인할 수 있는 기능이다.

data의 값으로 로그인 한 유저 자신이 속해 있는 채팅방 목록 (방번호-1)들을 담아 보낸 뒤 그 for문을 돌려 하나씩 그 방이 현재 존재하는지 확인을 한다. ( io.sockets.adapter.rooms.get(data[i] 만약 없다면 undefined가 나온다. ) 이로 인해서 undefined가 나오지 않으면 상대방이 현재 접속해 있다는 것을 확인할 수 있다. 그리고 이렇게 필터링 된 값들을 다시 클라이언트 소켓으로 보내고 클라이언트는 이 값을 바탕으로 프론트에 그려줄 수 있다.

 

3. on joinRoom

 

자신이 채팅방에 들어갔을 때 실행되는 이벤트이다.

data에 해당 방 번호가 들어있다. 이 값을 사용하여 join으로 방에 입장하자.

단  방에 입장하기 전에, 상대방이 현재 그 방에 있고, 미리 보낸 메시지가 있을 수도 있기 때문에 ( 안읽음 표시 )

안읽음 표시를 제거해주기 위해서 reload를 해주는 이벤트를 먼저 일으킨다.

(내가 채팅방에 있고 상대방에 들어왔을 때 나에게 발생하는 이벤트)

 

그 이후에 방을 입장하자

 

4. on leaveRoom 

 

방에서 나갈 때의 이벤트이다.

data의 값에 해당 방을 받아온 뒤 leave를 사용하여 방에서 퇴장하는 것을 해주었다.

 

5. on disconnect

 

소켓과 연결이 끊겼을 때 발생하는 이벤트

 

postApi

각 라우터에서  postApi라는 걸 사용하는 것을 확인할 수 있다. 여기에 프로시져 이름과, 프론트에서 받아온 데이터, 그리고 res를 넣어주었다. res를 넣은 이유는 저 postApi에서 값을 return할 수 있는 방법을 못찾았기에 어쩔 수 없이 저 함수 안에서 res.send()를 사용하기 위함이다.

 

postApi의 구조이다. 사실 이 구조는 내가 작성한 것이 아니라 잘 모른다.

mysql에 콜을 보내고 그에 대한 값을 payload에 담아서 response로 보내는 역할을 하는 것이다.

pool.js

mysql과 연결할 수 있는 것인데 이 것 역시 내가 작성하지 않아 잘 모른다.

이렇게 기본 node 구조로 만들어 보았다.