반응형

현재 중고책 기부 프로젝트를 진행하고 있습니다.
유저들끼리 중고책 기부를 하기 위해 채팅이 필요하며,
다수가 참여하는 유저 채팅보다는 일대일 채팅만 필요한 상황입니다.

 

일대일 채팅만 구현해야 한다고 가정

 

user1이 user2 에게 채팅 신청을 한다.

user2는 user1이 채팅 신청한 것을 알아야 한다.

 

user1 user2의 채팅방이 데이터 베이스에 저장된다.

user1, user2는 각각 해당 채팅방을 검색할 수 있어야 한다.

어떻게 저장을 하는 것이 효율적일까?

 

해당 채팅방에 채팅을 하면, 채팅을 한 사람이 누군지만 기록하면 된다.

채팅 기록은 채팅방 id 와 연관관계를 형성하고 있기 때문이다.

 

 

기본적인 스키마 디자인

 

ChatRoom: 
chatRoomId (PK)
participant1 (user1의 ID)
participant2 (user2의 ID)


Message: 
messageId (PK)
chatRoomId (FK, ChatRoom 참조)
senderId (메시지를 보낸 사용자의 ID)

content (메시지 내용)
timestamp (메시지가 보내진 시간)

 

고민했던 것

participant1 (user1의 ID)
participant2 (user2의 ID)

순서를 어떻게 처리하는게 효율적일까? 중복을 방지해야 할 수도 있다.

 

1. nickname 정렬을 한다.

nickname을 바로 알 수 있지만, member-id를 통해 nickname을 받아와야 한다.

 

2. member-id 정렬을 한다.

member-id 가 RequestHeader를 통해 들어오기 때문에 바로 조회할 수 있다.

닉네임은 알 수 없다.

 

중복방지는 필요가 없었다. 유저끼리 여러 책을 교환하는 상황이 나올 수 있다.

 

 

해결방법

nickname, member-id 둘다 message에 저장하기로 했다.

message 데이터를 구별하기 위해 member 서버에 다시 요청을 계속 보내는 것이 부담스럽다.

DB저장 공간을 희생시키며 요청 횟수를 줄이기로 했다.

 

Message: 
messageId (PK)
chatRoomId (FK, ChatRoom 참조)
senderId (메시지를 보낸 사용자의 ID)

senderNickname (메시지를 보낸 사용자의 닉네임) 추가

content (메시지 내용)
timestamp (메시지가 보내진 시간)

 

 

User Flow

사용자가 자신이 참여하고 있는 채팅방을 본다.

ChatRoom - participant1 (user1의 ID), participant2 (user2의 ID) 둘중 하나라도 매칭되면 해당 채팅방을 보여준다.

 

사용자가 채팅방 하나를 누를경우 해당 채팅방 채팅기록을 보여준다.

채팅 기록들은 senderId가 자신이라면 오른쪽으로 배치, 아니라면 왼쪽으로 배치

 

 

추가적인 고려 상황

채팅 기록은 무조건 실시간으로 구현해야 한다.

하지만, 채팅방 리스트는 실시간으로 구현해야 할까?
알림이 오면 채팅방 리스트를 볼텐데, 그때 http통신을 다시 하지 않을까?

사용자 편의성을 위해 실시간으로 채팅방 리스트까지도 실시간으로 구현하는게 좋을 것 같다.

그리고 채팅방마다 마지막 채팅 내역 또한 실시간 기능이다.

읽지 않은 채팅 개수 까지는 필요하지 않을 것 같다. (추후 고려 사항)

 

 

WebSocket을 사용할까? SSE를 사용할까? 이 부분도 기술 스택을 무엇을 이용해야 할지 생각해봐야 한다.

> WebSocket을 사용하기로 했다.


채팅방 리스트까지 실시간으로 구현하려면, WebSocket을 채팅방을 클릭하면 WebSocket 통신을 열어야 하고,
채팅 기록만 실시간으로 구현한다면, 채팅방을 누른 이후부터 WebSocket 통신을 열어야 한다.

> 사용자 편의성을 위해 채팅방 리스트까지 실시간으로 구현하기로 했다.
   채팅 위젯을 열면, ws 연결

 

구현해야 할 실시간 기능들

> 채팅 방 추가, 채팅 방의 마지막 채팅, 채팅 내부 기록

반응형

+ Recent posts