웹소켓 2편에서는 Socket.io패키지의 개념과 다양한 메서드들에 대해서 알아보자
웹소켓(WebSockt), 실시간 채팅 구현하기(NextJS, Express) < 1 >
Socket.io
는 웹소켓 연결을 통해 클라이언트와 서버간에 실시간 양방향 통신을 가능하게 하는 JS라이브러리이다.
Event
는 소켓 연결을 통해 클라이언트와 서버간에 전송 된 메세지이다.
Event
이름은 서버와 클라이언트에서 동일하게 선언되어야 한다.
Event
는 역할에 따라서 이름을 자유롭게 정의할 수 있다.
Event
에 담기는 데이터는 JSON, 문자열, 이진 등 모든 형식의 데이터 포함이 가능하다.
Namespace
는 클라이언트와 서버 간의 별도의 통신 채널이다.
단일 소켓에서 여러 Namespace
를 정의할 수 있으며 클라이언트는 특정 Namespace
에 연결하여 해당 Namespace
의 다른 클라이언트에게만 이벤트를 수신하거나 송신할 수 있다.
즉, 네임스페이스는 기본적으로 URI 경로와 비슷한 역할을 하며, 동일한 서버 내에서 다른 클라이언트 그룹을 위한 독립된 통신 채널을 제공한다.
http://localhost:5000/users -> ws://localhost:5000/users
http://localhost:5000/channels -> ws://localhost:5000/channels
예를 들면 위와 같이 API호출 분류에 따라서 유저정보와 관련된 API면 해당 API호출 도메인의 첫번째 엔드포인트로 "users"를 정의하는거처럼 Namespace
도 비슷한 연결을 해서 나눠진 Namespace
에 특정 클라이언트는 소켓연결을 시키거나 연결을 하지 못하게 하는 용도로 활용이 가능하다.
Room
은 함께 결합 된 소켓 그룹이다.
소켓은 여러 Room
에 합류하거나 떠날 수 있다.
Room
은 연결된 모든 소켓에게 송신하는 대신 특정 클라이언트 그룹에게만 메세지를 송신하는 유용하다.
Namespace
안에 그룹화된 소켓 그룹으로써 예를 들면 카카오톡에서 "그룹채팅"과 비슷한 역할이다.
Socket
은 클라이언트와 서버간의 연결을 나타낸다.
만약, 클라이언트와 서버가 소켓으로 연결된다면 각각의 연결은 id를 부여받게 되는데 이를 소켓id라고 한다.
즉, 위 그림에서 Room
공간 안에 있는 각각의 Socket
은 클라이언트 자체를 나타내며 각각의 연결된 클라이언트를 구분할 수 있는 소켓id가 되는 것이다.
public
방식은 연결된 모든 클라이언트에게 메세지가 전송되는 경우이다.
Socket.io에서 io.emit
은 연결된 모든 클라이언트에게 메세지를 broadcast하는 방법으로, 채팅 메세지와 같은 일반 메세지를 연결된 모든 클라이언트에게 보내는 데 유용하다.
// 서버 측
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
io.emit('chat message', msg); // 연결된 모든 클라이언트에게 메시지 통신(브로드 캐스트)
});
});
// 클라이언트 측
socket.on('chat message', (msg) => {
console.log(`Received message: ${msg}`);
});
io.on
전체 웹소켓 서버와 관련된 이벤트 처리
말 그대로 현재 소켓에 연결된 모든 클라이언트의 이벤트를 처리하는 메서드이자 영역이다.
socket.on
개별 클라이언트 소켓과 관련된 이벤트 처리
Private
은 특정 클라이언트에게 메세지를 보낼 때 사용한다.
Socket.io에서 socket.emit
은 특정 클라이언트에게 메세지를 보내는 방법으로, 알림 또는 개인 메세지를 특정 클라이언트로 보내는 데 유용하다.
// 서버 측
io.on('connection', (socket) => {
socket.on('send notification', (msg, recipientId) => {
io.to(recipientId).emit('notification', msg); // 지정된 수신자에게 메시지 보내기
});
});
// 클라이언트 측
socket.on('notification', (msg) => {
console.log(`Received notification: ${msg}`);
});
Broadcasting
은 발신자를 제외한 모든 클라이언트에게 메세지를 전송할 때 사용한다.
Socket.io에서 socket.broadcast.etmi
은 발신자를 제외한 모든 연결된 클라이언트에게 메세지를 송신하는 방법으로, 특정 방에 "Join", "Exit"할 경우 기존 방에 있던 클라이언트에게 알림을 보내는데 유용하다.
// 서버 측
io.on('connection', (socket) => {
socket.on('user join', (username) => {
socket.broadcast.emit('new user', username); // 발신자를 제외한 연결된 모든 클라이언트에게 메시지 통신(브로드 캐스트)
});
});
// 클라이언트 측
socket.on('new user', (username) => {
console.log(`New user joined: ${username}`);
});
클라이언트에서 서버로 또는 서버에서 클라이언트로 이벤트를 보내는 데 사용한다.
첫번째 인자로 이벤트 이름, 두번째 인자로 보낼 데이터가 정의된다.
socket.emit('chat message', 'Hello, world!');
/////////// 이벤트 이름 ///// 보낼 데이터 ////
특정소켓이나 방에 이벤트를 방출하는 데 사용한다.
이벤트가 전송 될 소켓id 또는 방 이름이라는 하나의 인수가 필요하다.
io.to('12345').emit('chat message', 'Hello, world!');
///// 특정 소켓 ////// 이벤티 이름 ////// 보낼 메시지 ////
클라이언트 또는 서버에서 이벤트에 대한 리스너를 등록하는데 사용한다.
첫번째 인자로 이벤트 이름, 두번째 인자로 이벤트로 전달된 데이터를 처리하기 위한 콜백함수가 정의된다.
socket.on('chat message', (message) => {
//////////// 이벤트 이름 //// 콜백 함수 //////
console.log(`Received message: ${message}`);
});
자체 소켓 및 이벤트 세트로 새로운 Namespace
를 만드는 데 사용한다.
인자로 Namespace
이름을 정의한다.
const chatNamespace = io.of('/chat')
Socket.io는 클라이언트와 서버간에 WebSocket 의 연결을 설정하여 작동한다.
서버는 들어오는 연결을 확인하고 클라이언트가 방출하는 이벤트를 처리한다.
클라이언트가 이벤트를 방출하면 서버는 이벤트를 수신하여 클라이언트로 응답을 다시 보내거나 동일한 Namespace
또는 Room
에 있는 다른 클라이언트로 이벤트를 Broadcast할 수 있다.