진행했던 프로젝트에서 socket으로 채팅 기능을 구현할 일이 있었다. 단순히 실시간 채팅 주고 받는 것은 예전에 실습이나 프로젝트로 몇 번 해봤는데, 카톡처럼 채팅방 리스트가 있고 채팅 내용을 저장하는 방식은 처음 구현해보는 것 같아서 한 번 정리해보고자 한다.
채팅 기록을 저장하지 않는 단순 실시간 채팅 기능에 대한 워크플로우를 세워보자.
워크플로우는 개발자에 따라 다양하게 나올 수 있어 밑의 예시는 참고용으로만 봐주길 바란다. (그러나 ‘단순 실시간 채팅’의 경우 워낙 단순한 구조인 만큼 대부분의 개발자가 아래와 같은 형식으로 개발을 하게 될 것이다.)

클라이언트들은 채팅 기능을 하는 브라우저에 접속한다. 이때, A-Room 라는 이름의 방으로 입장한다.
클라이언트 A와 B에서 Socket 연결을 시도한다.
서버에서 핸드셰이킹을 하여 Socket Session 연결을 완료한다.
클라이언트 A가 A-Room에 채팅을 보내기 위해 연결된 Socket session으로 서버에 메시지를 보낸다.
이때, 메시지의 형식은 서버와 미리 정해놓은 규약(명세)으로 한다.
예시
{
"room": "A-Room",
"message": "Hi",
"sender": "A"
}
서버에서 메시지를 받아 해당 메시지를 보내고자 하는 방의 멤버들에게 다음과 같은 메시지를 보낸다.
예시를 기준으로 진행한다면, A-Room에 해당하는 멤버를 우선 찾고, 해당 멤버와 연결된 session을 통해 서버에서 적절한 메시지를 보내면 된다.
이때, 메시지의 형식은 서버와 미리 정해놓은 규약(명세)으로 한다.
예시
{
"message": "Hi",
"sender": "A"
}
클라이언트가 서버로부터 5번과 같은 메시지를 받으면 화면에 해당 메시지를 띄워준다.
브라우저를 끌 때 연결된 socket을 close한다.
본 프로젝트에서 제공되어야 하는 채팅 페이지 UI와 관련 기능들은 다음과 같았다. 디자인에 따라 구현 구조나 방식이 달라질 수 있기 때문에 본 포스팅에서 기준이 될 채팅 UI를 참고바란다.

위와 같이 채팅 기록을 저장하고, 여러 개의 채팅방을 갖는 실시간 채팅 기능에 대한 워크플로우를 세워보자. (WebSocket 기반, 브로드캐스팅 라이브러리X)
워크플로우는 개발자에 따라 다양하게 나올 수 있어 밑의 예시는 참고용으로만 봐주길 바란다.

A는 채팅 기능을 하는 브라우저에 접속한다.A는 채팅방 리스트를 get하는 api를 통해 서버에 HTTP 요청을 보낸다.A가 멤버로 있는 채팅방 리스트를 필터링하여 클라이언트에 반환한다.A는 서버와 socket 연결을 시도한다.A가 채팅방 리스트에서 원하는 채팅방에 접속한다. 이때, 서버와 맺어진 socket session을 통해 해당 채팅방의 채팅 기록을 요청한다. 예시
{
"room": "A-Room",
"event": "enter", // 소켓 사용 시 메시지에 event type 명시하는 것이 일반적
"sender": "A"
}A에게 받은 메시지를 보고 연결된 session을 통해 A에게 해당 룸의 채팅 기록을 보낸다.예시
{
"event": "sendLog",
"log": [
{
"sender": "B",
"message": "Hi"
},
{
"sender": "A",
"message": "Hello"
}
]
}A가 현재 접속한 채팅방에 채팅을 보내기 위해 연결된 socket session으로 서버에 메시지를 보낸다.예시
{
"event": "sendMessage",
"room": "A-Room",
"message": "hihi",
"sender": "A"
}A-Room에 해당하는 멤버를 우선 찾고, 해당 멤버와 연결된 session을 통해 서버에서 적절한 메시지를 보내면 된다.예시
{
"event": "sendMessage",
****"room": "A-Room"**,**
"message": "hihi",
"sender": "A"
}A-Room 의 멤버였던 클라이언트 B가 9번과 같은 메시지를 받았다면, 브라우저에 띄워놓은 채팅방 리스트에서 해당 채팅방 컴포넌트를 찾은 뒤 해당 방을 최상단으로 끌어올린다.A-Room 채팅방에 접속해 있다면, 받은 메시지를 가공하여 채팅을 UI로 띄운다.⚠️ 주의: 모든 소켓 메시지를 보낼 때는 서버와 클라이언트가 미리 정해놓은 규약(명세)을 지킨다.
다음에는 실제 Front에서 Socket을 적용하는 방법과 코드를 정리해볼 예정이다.