실시간 : socket + redis pub/sub

해피데빙·2023년 2월 1일
0

socket

  • 프로세스가 드넓은 네트워크 세계로 데이터를 내보내거나
  • 그 세계로부터 데이터를 받기 위한 실제적인 창구
  • 프로세스가 데이터를 보내거나 받기 위해서는 반드시 소켓을 열어서 데이터를 보내거나 받는다

이렇게 말하면 정말 어려운데 쉽게 말하면,
채팅 서비스에서 실시간으로 다른 사람들이 보내는 톡을 읽으려면
1. 다른 사람이 톡을 보낸다
2. db에 저장된다
3. 내 쪽에서 톡을 읽기 위해 요청을 보낸다
이런 과정이 필요하다

하지만 이렇게 하려면 다른 사람이 db를 업데이트할 때마다 새롭게 받아와야 하는데,
내 쪽에서는 언제 다른 사람이 새로운 톡을 보냈는지 알 수 없다.

그러므로 socket.io를 통해 이를 해결한다.
socket은 이미 서비스에 접속한 순간(즉 서버와 연결된 순간) 열리고 서비스를 나갈 때까지 열려있다(이건 정확히 잘 모르겠다)

서버
1. 요청이 오기도 전에 subscribe를 시킨다
redis의 pub/sub을 통해 특정한 이름으로 (ex.chat_room) redis에 서버를subscribe시킨다. talkId가 일치하는 이벤트가 일어났을 때 해당 event 이름으로 data를 넘준다.

  1. 요청이 올 때
    1)톡방의 경우 톡방 안에 있는 사람들만 연결을 하면 되니까 socket room을 만들어서 한꺼번에 관리를 한다. 클라이언트에서 요청을 통해 socket 연결이 되면 talkId가 같은 연결끼리 하나의 room을 만든다

2)여러 서버를 사용하는 경우 클라이언트에서 요청이 분산되어 각각 같은 talkId에 대한 다른 socket room을 만들 수 있다. 그럼 누군가 톡을 보냈을 때 같은 서버를 쓰고 있는 사람만 톡을 볼 수 있게 된다. 그러므로 서버끼리 동기화를 하기 위해 redis를 사용해야 한다 (1번 보기)

3) 톡을 post하는 요청이 오면 db 저장 등 처리 후 redis에 event이름과 data를 넘긴다

4)server.ts에서 socket에 event의 이름과 data를 넘겨준다. 어떤 이벤트와 데이터를 넘겨줄지는 따로 타입을 정의한다.

  1. 클라이언트에서 event와 data를 받아서 표현해준다

클라이언트
1.특정 event에 대해 data를 받는다
2. 그린다
ex. 새로운 글이나 톡을 쓰는 경우 바로 클라에서 표현을 하면 socket을 통해서 자신의 글도 전체적으로 전달되기 때문에 같은 글이 두 개씩 올라갈 수 있다. 그러므로 아예 socket을 통해 받은 글만 표현을 하고 클라에서 자체적으로 표현을 하지 않는다. 또는 socket을 통해 받은 데이터가 그리려고 하는 데이터가 있는지 확인해 중복을 피한다.

profile
노션 : https://garrulous-gander-3f2.notion.site/c488d337791c4c4cb6d93cb9fcc26f17

0개의 댓글