초보 개발자

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

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

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

taehyeki 2022. 5. 22. 13:23

채팅방에서 나간 경우

 

방에서 퇴장한 경우 화면도 destroyed가 되기 때문에 이 전에 주었던 이벤트 리스너를 다 없애주어야 한다.

 

서버와의 연결이 끊긴 후에 다시 연결 된 경우 vuex의 특정 프로퍼티를 하나 올려줌으로써 소켓이 바뀐 걸 감지할 수 있도록 만들어 주었다.

 

따라서 이걸 watch로 감시해준다.

 

기존에 있던 소켓에 이벤트를 제거하고 다시 붙여주었다. 사실 enterRoom, chatSet만 설정해도 작동은 잘 되는 것 같은데 통일성을 위해서 나머지도 다 지우고 다시 붙여주었다. ( 어떤 건 안 붙여 줘도 작동이 잘 되고, 또 어떤 건 붙여줘야 하는지 잘 모르겠다... )

 

채팅 삭제

카톡을 하다 보면 채팅을 삭제해야하는 경우가 있다. 이 기능을 만들어 보면 좋을 것 같다. 크게 생각해야될 부분은 두가지이다.

 

1. 먼저 채팅을 삭제하려면 각 chat을 구분할 수 있는 고유의 값이 필요하다 이 부분은 chat의 인덱스 값을 사용하면 될 것이다. 

 

2. 삭제를 하면 상대방에게도 삭제 되었다고 바뀌어야한다 (실시간), 채팅방에서뿐만아니라, 채팅방 목록에서도 바뀌어야 할 것이다.

 

먼저 결과먼저 보여드리면 아래와 같다.

 

 채팅을 삭제하였을 때 채팅방 화면

 

채팅 삭제하였을 때 채팅방 목록 화면

가장 먼저 편집 버튼을 누르면, 메시지 삭제 버튼과 취소 버튼이 생기도록 해야할 것이다.

dpnone 클래스는 display : none이다. 클릭했을 때 토클을 사용하여 감추고 보이게 할 것이다. 

자세한 사항은 아래를 참고하자

마운트가 되면 기능이 넣어지도록 하였다. 여기서 checkBoxes를 미리 선언해 둔 것을 확인할 수 있다.

 

그 이유는 편집 버튼을 눌렀을 당시에 존재하는 채팅만 클릭할 수 있도록 한 것이다. ( 새로 작성한 채팅은 체크 할 수 없다 ) 따라서 저 변수를 다같이 공유하여 같은 상태의 체크박스들을 바라보는 것이다. 만약 새로 작성한 채팅을 체크하려면 다시 취소를 누른 뒤 편집을 눌러야 할 것이다. 여기서 특별한 것은 this.delChatList이다. 이건 체크한 채팅들의 id값이 들어가는 곳인데, 편집 버튼, 취소 버튼, 메시지 삭제 버튼을 누르건 다  this.delChatList를 마지막에 초기화를 시켜 버린다.

 

메시지 삭제를 누르면 확인하는 창이 나오고 ( cofirm ) 거기서 확인 버튼을 누르면 본격적으로 채팅이 삭제된다.

 

아래는 체크박스이다. chat.DELETED는 삭제 된 메시지라면 1이들어오고, 아니면 0이들어있다. 따라서 삭제된 메시지는 체크할 수 없도록 해준 것이다. 여기서 체크를 하면 change이벤트가 실행이되고 파라미터로 chat id를 넘겨준다.

change에 담긴 함수이다. indexOf를 사용하여 체크한 아이디가 배열에 존재하면 삭제하고, 아니라면 푸쉬해주었다.

이로써 체크박스에 체크를 하면 delChatList에 그 값들이 담겨 있다.

삭제를 하면 beforeDeleteChat함수가 실행이 될 것이다. 그 함수의 내용은 아래와 같다.

디비에서 사용하기 위해 파싱을 하고 ( 1,2,3,4,5 와 같은 형태로 바뀜 )그 값을 delList에 넣어 deleteChat을 실행시킨다.

deleteChat은 USER_ID와 delList를 api를 통해 백엔드에 보낸다. 

백엔드는 그 데이터를 받아서 db로 보낸 뒤 프로시져를 실행시켜 해당 채팅들을 삭제시킨다. 다시 돌아와서 채팅 리스트들을 비워주고,

새로운 채팅목록들을 불러오는 this.chat을 실행시키자. 그 뒤 newChats(채팅창에 적은 내용이 들어있음)을 비워주고, 

 

여기서 chats에 await을 안쓰면 뷰 특성상 newChats가 바뀔 때 newChats를 html에서 사용하고 있다면 화면이 재 렌더링이 된다. 하지만 채팅도 재렌더링이 되고 (getChats라는 게터로 디비에서 가져온 내용을 그림) newChats도 없어지니 부자연스러워 진 것이다. 하지만 await을 사용하니 신기하게 부자연스러운게 사라졌다..? 사실 이해는 되지 않는다.

 

그리고 그 위에 deleChat도 비슷하다. vuex안에서도 await을 사용하였고 여기서도 사용하였는데, 둘 다 사용해주지 않으면 데이터를 제대로 못불러올 때가 있다. 이 부분도 사실 잘 이해가 되지 않긴하다.

 

소켓에 이벤트를 보낸다. 소켓에 이벤트를 보내는 이유는, 삭제되었기 때문에 상대방도 그 메시지가 보이면 안되기 때문이다. 그래서 소켓을 사용하여 화면을 업데이트 시켜주어야 한다. 이벤트 명은 didYouDelete 이고, 보내는 값은 room 번호를 보내준다. 소켓아이디는 필요없다. 잘못 넣었따.

 

서버측 소켓에서 아래와 같이 이벤트 리스너를 달아주자. didYouDelete가 들어오면  받아온 룸번호로 yesDelete라는 이벤트를 다시 보낸다. 그리고 room-1 에도 이벤트를 보낸다. 여기에 보내는 이벤트명은 forRoomList이다. room-1은 채팅방 목록에 있는 방들이다. 채팅방 목록에 있어도 마지막 메시지가 삭제되었습니다 라고 값이 바뀌어야 하기 때문이다.

서버측 소켓

그럼 클라이언트측에서도 이벤트 리스너가 있어야할 것이다. 먼저 플러그인에서 함수를 만들고 각 함수를 실행시키면 이벤트 리스너가 실행되도록 해준다. 이렇게 해준 이유는 fn이라는 함수를 받아서 이벤트 리스너 콜백함수로 넣어주기 위해서이다. 

채팅방이 생겼을 때 (created) fn3라는 함수를 이벤트 리스너에 넣어주었다. fn3함수는 해당 방에 들어있는 채팅내용을 다 가져오는 함수이다. 가져와서 vuex에 저장하고 그 게터를 html에서 사용하여 화면이 재 랜더링 된다.

이 처럼 채팅룸 목록의 create가 될 때 나머지 하나도 리스너를 달아주어야 한다.  chatRooms역시 채팅방 목록을 불러오는 함수이다. 

이로써 위의 영상과 같이 잘 작동할 수 있게 되었다.