개요
채팅을 구현하는 것은 이번이 두 번째입니다. 처음 구현할 때는 웹 개발을 처음했을 때라 웹소켓보다 기본적인 API에 집중했습니다. 그러다 보니 소켓 관련 부분은 게임 파트 동료가 만들어둔 것을 사용하는 형식으로 했고, 디테일이 부족했습니다. 하지만 이번에 채팅을 한 번 더 구현할 기회가 생겨 관련하여 공부하고, 기록으로 남겨볼 예정입니다.
본문
현재 ec2 docker의 WAS의 아키텍처는 무중단 배포를 위해 인스턴스가 두 개 존재합니다. 때문에 클라이언트와의 통신 요청-응답 사이에 상태를 서버에서 저장하면 안 됩니다. DB 등의 또다른 인스턴스에서 저장해야 한다는 이야기이죠. 때문에 In-memory caching을 할 수 있는 Redis 등을 이용하여 서버 소켓을 저장해야 합니다. 이렇게 redis adapter를 이용하여 서버 소켓 객체를 받으면 어느 서버 인스턴스든지 이를 통해 연결된 클라이언트 소켓의 ID와 존재하는 방을 알 수 있습니다.
room
console.log('rooms', serverSocket.sockets.adapter.rooms)
// output
rooms Map(4) {
'hpHrhLuOFNPuAAAC' => Set(1) { 'hpHrhLuOFNPuAAAC' },
'1' => Set(3) {
'hpHrhLuOFNPuAAAC',
'Kt0IeYreQTXIAAAE',
'7d2iS0GAzF5kAAAH'
},
'Kt0IeYreQTXIAAAE' => Set(1) { 'Kt0IeYreQTXIAAAE' },
'7d2iS0GAzF5kAAAH' => Set(1) { '7d2iS0GAzF5kAAAH' }
}
rooms는 위와 같이 serverSocket.sockets.adapter.rooms에 존재하는 방과 해당 방에 들어가 있는 클라이언트 목록을 볼 수 있습니다. 현재 '1'이라는 방과 그 방 안에 있는 클라이언트 세 명이 존재하죠. 클라이언트는 기본적으로 자신의 소켓 id를 방으로 가지게 됩니다. 때문에 하나의 방만 존재함에도 rooms 객체에는 네 개의 방이 있습니다. 때문에 방만 필터하고 싶다면 소켓 id를 제외하고 가져와야 합니다.
클라이언트 소켓 ID
소켓 id는 serverSocket.sockets.adapter.sids에서 얻을 수 있습니다. sids는 아래와 같습니다.
console.log('sids', serverSocket.sockets.adapter.sids)
// output
sids Map(3) {
'7Uy5Jqn_SufcAAAK' => Set(2) { '7Uy5Jqn_SufcAAAK', '1' },
'EAQ1XXIx-xuVAAAN' => Set(2) { 'EAQ1XXIx-xuVAAAN', '1' },
'Mya1TbP-4qoAAAAQ' => Set(4) { 'Mya1TbP-4qoAAAAQ', '1', '2', '3' }
}
sids 객체는 Map<key, value>으로 자신의 소켓 id를 key로 하고, 자신이 입장해 있는 방의 id를 set으로 value를 갖고 있습니다. 클라이언트는 모두 자기의 소켓 id로 된 방에 들어가 있습니다. 세 번째 클라이언트만 추가로 두 개의 방에 더 들어간 모습입니다.
'개발 일지' 카테고리의 다른 글
socket.io의 특징과 장단점 (0) | 2024.08.02 |
---|---|
Socket.io이란? 웹 소켓과의 차이점은? (0) | 2024.07.19 |
스타트업 취업 4주차 후기(SI는 어떨까?) (2) | 2024.04.11 |
API 명세서 작성 규칙(convention) (2) | 2024.02.12 |
[PA] User 관련 ERD 설계 (0) | 2024.02.01 |