socket으로 구현한 채팅방에 총 참가자 수를 구현하려고 한다. 추후에는 따로 배열이나 디비를 생성해서 관리를 할 것이지만 socket.io에서 제공하는 api가 있을것 같아 찾아보았다.
socket.io의 room은 adapter로 구현이 된다. Adapter는 서버사이드 컴포넌트로 소켓과 room들의 관계를 저장하고 모든 클라이언트에게 이벤트를 브로딩캐스팅 하는 역할을 한다.
어댑터는 sids, rooms라는 두개의 Map객체가 있는데 이중 rooms 활용하여 특정 room에 참여한 소켓들을 확인 해 볼것이다.
Map과 Set은 자바스크립트의 오브젝트 유형인데 오브젝트라고 생각하고 봐도 아래 내용 이해에 문제는 없을듯하다.
Map,Set에 관한 MDN설명 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Keyed_collections#maps
키기반의 컬렉션 - JavaScript | MDN
이번 장에서는 입력된 키값을 기준으로 정렬되는 데이터의 집합(자료 구조)에 대해 소개 할 것이다. Map과 Set은 입력된 순서대로 반복적으로 접근 가능한 요소들을 포함하고 있다.
developer.mozilla.org
const room='testroom'
socket.join(room);
console.log(io.of('/').adapter.rooms);
io는 소켓 서버를 담고 있는 객체인데, 네임스페이스를 분리하지 않았기 때문에 현재 경로('/')의 어댑터들을 확인 한다.
출력 해 보면 testroom에 들어간 소켓id와 testroom이 각각 저장되어있다.
새로운 소켓이 test룸에 참여한 뒤 출력해 보면 다음과 같다.
새로운 유저의 socket이 Map에 추가가 되고, testroom안에 새로운 유저가 추가된다.
새로운 유저가 기존의 testroom이 아닌 새로운 newroom에 가입 한다면 새로운 newroom도 추가가 되어진다.
새로운 user의 socket id가 추가가 되었고 새로운 newroom도 추가가 된 것을 볼 수 있다.
이렇게 확인 해 본 결과
socket.join으로 특정 room에 들어가면 adapter.rooms에는 들어온 socket의 id를 저장하고 특정room안에도 socket id를 저장해 두는것을 볼 수 있다.
여기서 내가 원하는것은 특정한 room에 들어있는 유저의 숫자(socket의 개수)이기 때문에 해당 room의 이름을 key로 써서 손쉽게 확인 할 수 있다.
현재 adapter.rooms에는 다음과 같이 저장되어 있다.
여기서 나는 testroom에 있는 유저들만 보고싶기 때문에 testroom을 정보만 받아온다. map객체의 get함수로 불러올 수 있다.
// room='testroom'이었음.
console.log(io.of('/').adapter.rooms.get(`room`));
그러면 이렇게 testroom에 있는 소켓들의 id가 set 컬렉션으로 저장되어있음을 볼 수 있다.
배열(array)는 array.length로 배열의 길이를 바로 구할 수 있듯
set은 size로 구할 수 있다.
console.log(
`room ${room}의 참가자 수 : ${ io.of('/').adapter.rooms.get(`${room}`).size }`
);
쨘