-
Notifications
You must be signed in to change notification settings - Fork 0
DirectMessage Service
빠른 응답성을 요구하는 실시간 채팅 서비스인 Direct Message 서비스에 대해 설명합니다. 실시간 소켓 통신을 위해 SignalR
을 사용했고 DB
저장 시간을 줄이고 빠르게 사용자에게 응답하기 위해 빠른 메모리 DB
인 Redis
를 사용했습니다. 사용자가 전달해 온 데이터가 정합성 검사를 통과하면 1차적으로 Redis
에 저장하고 백그라운드 서비스에서 DB
로 영구저장 됩니다.
NAME |
REASON FOR USE |
---|---|
SignalR | 소켓을 사용한 실시간 통신을 하기 위해서 |
Redis | 실시간 통신의 응답성을 향상시켜 주기 위해서 |
Entity Framework CORE | ORM |
-
Client가 로그인을 성공하고 서비스를 이용할 준비를 마쳤다.
-
서버는 사용자의 ID와 Connection ID를 {key:value} 형태로
Connection Manager
에 저장해둔다.1 -
Client에서 chat창을 연다.
-
HTTP 통신으로 기존에 했던 대화를 가져온다.
-
Client에서 Direct Message를 다른 Client에게 보낸다.
-
소켓을 통해 메시지 정보가
DirectMessageHub
에 보내지면 메시지를 파씽하고 비동기적으로Redis
에 저장한다.2Redis
에서 저장하는 동시에2번
에서 저장한Connection Manager
를 이용해 받는 사람의 Connection ID를 가져와 상대 Client에게 메시지를 보낸다. -
Redis
에 저장된 데이터는 멀티쓰레드 세이프한Channel<T>
을 통해 DB 삽입 쓰레드와 pub/sub구조로 연결된다.Channel<T>
에 입력되는 데이터는 비동기 스트림 방식으로 DB 삽입 쓰레드에서 데이터를 폴링해 DB에 영구 저장된다.
CacheService
에서 빠른 응답성을 갖으면서 데이터 저장을 하기 위해 Redis
에 데이터를 전송하고 데이터 저장 유무와 관련없이 바로 리턴한다.
이렇게 하면 빠른 응답성을 요구하는 채팅 서비스에서 클라이언트는 즉각적인 응답을 받을 수 있다.
동시에 안전한 멀티쓰레드 pub/sub이 가능한 Channel<T>
자료구조를 이용해 비동기 스트림 방식으로 데이터를 폴링해 DB에 영구 저장한다.
-
Client에서 Direct Message 데이터가 들어온다
-
비동기적으로
Channel<T>
에 데이터를 저장하고 저장 유무에 상관없이 클라이언트에게 리턴한다. -
비동기 스트림 방식으로
Channel<T>
를 폴링하던 DB 삽입 쓰레드는Channel<T>
에 데이터가 입력 되는 즉시 그것으로부터 데이터를 가져와 DB 저장을 시도한다.
1: SignalR
은 각 Client마다 자신의 Connection Id를 갖고 Application은 Client를 User의 DB
Primarykey로 구분하기 때문에 둘의 연결관계를 만들어 줘야 SignalR
입장에서는 들어온 메시지에 들어있는 Id를 이용해 올바른 Client에게 응답을 전달할 수 있다.
2: 응답성이 중요한 소켓통신에서 DB
에 저장되는 지연시간을 최소화 하기 위해 빠른 Redis
에 저장 후 다른 쓰레드로 DB
에 영구 저장한다.