socket.io
란 서버와 클라이언트가 상호작용하는 웹 서비스 통신 기술인 WebSocket을 간단하게 사용할 수 있도록 도와주는 모듈이다. 서버와 클라이언트는 아래 코드와 같이 연결하여 서로 통신할 수 있도록 만들 수 있다.
(아래 서버 코드 예시는 Node.js
에서 쉽게 서버를 구성할 수 있게 해주는 express
를 사용했다.)
// server
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server, { cors: { origin: '*' } });
io.sockets.on('connection', (socket) => {
console.log('connected');
socket.on('disconnect', () => {
console.log('disconnected');
});
... // socket codes (emit, on)
});
server.listend(socketPort, () => console.log('socket io server listening'));
// client
const socket = io.connect(`http://${hostName}:${socketPort}`);
... // socket codes (emit, on)
위 예시에서 hostName 과 socketPort 변수는 적절하게 입력해주어야 한다. 위 코드와 같은 경우, eventEmitter
와 비슷한 형식인 emit
과 on
메소드로 서버와 클라이언트가 양방향 통신을 할 수 있게 된다.
채팅 기능을 생각하면 서버와 클라이언트가 통신할 때, 어느 한 클라이언트가 emit
한 메시지를 다른 모든 클라이언트가 받게되면 안된다. 특정 채팅방 안에 속해있는 클라이언트들만 해당 메시지를 받아야 한다. socket.io
의 namespace
와 room
은 이러한 기능을 구현할 수 있도록 도와준다.
namespace
는 기본적으로 전체 클라이언트가 속해있도록 설정되어있다. 이 설정을 변경하기 위해서는 서버와 클라이언트가 아래와 같이 연결하고 이벤트를 emit
하여야 한다.
// server (of 메소드 사용)
const chat = io.of('/chat');
chat.on('connection, (socket) => {
... // socket 연결 후 코드
});
// client (socket 연결 시 주소 변경)
io.connect(`http://${hostName}:${socketPort}/chat`, options);
// event emit
io.of('/chat').emit('event name', chatData);
위의 경우 namespace
가 /chat
에 속해있는 클라이언트만 통신하게 된다.
room
의 경우에는 namespace
안에 특정 그룹들을 만드는 개념이다. 아래와 같이 room
에 들어가고 나가게 만들 수 있으며, 해당 room
에게만 이벤트를 emit
하는 방식으로 채팅방과 같은 기능을 구현할 수 있다.
socket.join('chat room'); // 채팅방 입장
socket.leave('chat room'); // 채팅방 퇴장
io.to('chat room').emit('event name', chatData); // 채팅방 내 모두에게 이벤트 발송
socket.io
에서 namespace
, room
을 사용하지 않는 경우에도 특정 클라이언트에게만 이벤트를 emit
할 수 있는 방법이 크게 세 가지가 있다.
첫 번째는 나를 포함한 전체이다.
io.emit('event name', data);
두 번째는 나를 제외한 전체이다. (broadcast 객체 사용)
socket.broadcast.emit('event name', data);
세 번재는 특정한 하나의 클라이언트이다. (to 사용)
io.to(socketId).emit('event name', data);