0. 채팅 시스템 요구사항 분석
요구 사항 나열
- 채팅방에 접속 시 읽지 않은 메시지를 읽음 처리 해야한다.
- 채팅방에 접속 시에도 채팅방 메시지 전송 받는다면 휘발성 알림을 받는다.(휘발성 알림은 2초 후에 사라지고, 2초가 지나기전에 새로운 메시지가 도착하면 새로운 메시지로 대치되고 다시 2초 후에 사라진다.)
- 채팅방에서 메시지를 전송하면 채팅방에 접속되어있는 유저들에게 실시간으로 UI를 변경해야한다.
- 채팅방에 접속하고 있지않다면 공통 App Bar에 아직 읽지 않은 메시지 수를 메시지가 전송될 때마다 실시간으로 반영해야한다.
- 로그인을 하고 있지 않은 경우에는 아무런 알림을 받을 수는 없다.
1. 채팅방에 접속 시 읽지 않은 메시지를 읽음 처리
채팅방에 접속 시 채팅방의 메시지들을 가져오는데 이 때, 모든 메시지를 가지고 올 수 있고, 최근 몇개의 메시지만 들고 올 수 있다.
어쨌든 저쨌든 메시지를 가져올 때 그 메시지의 읽음 여부가 false이고, 메시지를 읽은 자와 전송자가 다를 경우에는 그 메시지를 새로 읽었다고 볼 수 있다. (1대1 채팅방에만 가능한 로직)
이 로직으로 새로 읽었는지 확인한 후 읽음 여부를 true로 변경하고 다시 영구 저장소에 반영해줘야한다.
메시지를 담을 영구 저장소를 RDBMS, NOSQL로 크게 선택할 수 있는데 데이터 양도 많고 조회양도 많기 때문에 NOSQL을 선택하고, redis와 mongo 중에서 값의 수정이 편한 mongo를 선택했다.
mongo의 updateOne을 이용해서 읽음 여부를 변경
2. 채팅방에 접속 시에도 채팅방 메시지 전송 받는다면 휘발성 알림을 받는다.(휘발성 알림은 2초 후에 사라지고, 2초가 지나기전에 새로운 메시지가 도착하면 새로운 메시지로 대치되고 다시 2초 후에 사라진다.)
메시지 전송 이벤트 발생 시 그 메시지의 채팅방의 상대방에게만 알림 이벤트를 발생 시킨다.
redis에 알림을 저장 시켜서 읽지 않은 메시지의 수를 계산할 때 편리하게 알림 수로 계산할 수 있다. (읽지 않았기에 알림이 발생하므로 읽지 않은 메시지의 수와 알림 수는 동일하다.)
3. 채팅방에서 메시지를 전송하면 채팅방에 접속되어있는 유저들에게 실시간으로 UI를 변경해야한다.
메시지 전송 이벤트 발생 시 그 메시지의 채팅방에 접속하고 있는 모든 이에게 메시지를 broadcast event 발생시켜 이벤트를 받으면 UI를 바로 처리하여 실시간으로 메시지를 반영한다.
그런데 만약 전송자의 상대방이 채팅방에 접속되어 있다면 읽은 여부가 바로 true가 되어야한다.
그래서 socket연결할 때 어떤 user가 어떤 socketId로 연결되어있는지를 저장하고 있다가 room에 상대방 socket이 접속하고 있다면 바로 읽은 여부를 true로 하고 메시지를 저장한다.
4.채팅방에 접속하고 있지않다면 공통 App Bar에 아직 읽지 않은 메시지 수를 메시지가 전송될 때마다 실시간으로 반영해야한다.
App Bar에는 읽지 않은 메시지 수가 5개이면 채팅 아이콘 옆에 '5'라고 표시를 해야하는데 이 숫자가 메시지가 전송될 때마다 실시간으로 처리되어야 한다.
그래서 redis에 저장되어있는 알림의 수를 읽지 않은 메시지의 수로 처리하면 편하게 할 수 있다.
새로운 메시지가 전송되면 채팅방 관련된 socketId에 알림의 수를 새로 업데이트하라고 이벤트를 보내면 이벤트를 받는 즉시 다시 redis에서 알림의 수를 새롭게 가져온 후 UI에 반영한다.
5. 로그인을 하고 있지 않은 경우에는 아무런 알림을 받을 수는 없다.
redis에 저장되는 알림은 따로 조회할 수 없기 때문에 로그인하지 않은 유저는 휘발성 알림을 볼 수도 이전 알림을 조회할 수 없다.
그러나 읽지 않는 메시지의 수인 App Bar에는 로그인하는 순간 가져온다. 그 이후에는 1, 2, 3, 4 규칙을 적용받는다.
요구 사항에 맞게 node, redis, mongo 관점으로 프로세스를 말로 풀어보고 그림과 코드로 채팅 시스템을 구성해볼 예정이다.
필요하면 요구사항이 수정될 수 있고, 더욱 좋은 시스템을 위한 추가 기능이 생길 수 있다.