진행했던 프로젝트에서 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을 적용하는 방법과 코드를 정리해볼 예정이다.