-
Notifications
You must be signed in to change notification settings - Fork 0
웹소켓 방 관리 구조 개선
Gyeongsu Choi edited this page Dec 1, 2024
·
8 revisions
기존에는 로비에서 방에 입장했을 때 같은 방에 있는 유저들만의 통신 채널을 만들어주기 위해 Socket.IO에서 제공하는 join 메서드를 사용했습니다. join 메서드는 아래와 같이 사용하며 같은 roomId에 속한 클라이언트끼리의 데이터 송수신이 가능하게 됩니다.
// client: socket.io.Socket
client.join(roomId);
하지만 join 메소드를 통해 방을 관리하는 방식은 아래와 같은 두 가지 단점이 있었습니다.
첫 번째로, join 메소드는 Socket.IO 라이브러리에서 제공해주는 특수한 기능이므로 다른 웹소켓 라이브러리를 사용하게 되면 사용하지 못하게 될 가능성이 높습니다.
두 번째로, 아래와 같은 방식으로 특정 방에 있는 클라이언트들에게 메시지를 전송할 수는 있지만 roomId로 클라이언트 소켓을 조회할 수는 없었습니다.
// server: socket.io.Server
server.to(roomId).emit('chat', 'message');
이로 인해 다른 모듈에서 방에 메시지를 전송하기 위해서는 서버 소켓 자체를 넘겨야하는 문제가 있었습니다.
그래서 client들을 같은 채널로 묶어서 관리하는 기능을 Socket.IO 라이브러리에 의존하지 않고 직접 구현하기로 했습니다.
- EventClient 클래스
내부에 Socket을 가지고 있으며 그 외에도 nickname 등의 정보를 추가로 가질 수 있습니다.
class EventClient {
nickname: string;
socket: socket.io.Socket;
emit(event, ...args) {
this.socket.emit(event, ...args);
}
}
- Room 클래스
위 EventClient의 배열을 관리하며 이를 이용해 방에 있는 클라이언트들에게 메시지 전송이 가능합니다.
class Room {
roomId: string;
clients: EventClient[];
enter(client: EventClient) {
this.clients.push(client);
}
sendAll(event: string, ...args) {
this.clients.forEach((c) => c.send(event, ...args));
}
}
이렇게 구조를 변경하니 다른 모듈에서 특정 방에 메시지를 전송할 필요가 있을 때 Room 객체 하나만 전달하면 되니 서버 소켓을 전달할 때 발생할 수 있는 문제를 예방할 수 있었습니다.
web12-MafiaCamp