socket.io는 채팅방에 특화된 라이브러리라, 만일 양방향 통신 기술이 필요한데 채팅방이 아닌 다른 서비스를 구현 한다면 socket.io는 맞지 않을 수 있다.
npm i socket.io
socekt.io의 메소드의 특징은 클라이언트에서 발생하는 이벤트는 개발자가 임의로 설정할 수 있다는 점이다.
이벤트는 문자열로 지정하며 직접 이벤트를 발생시킬 수 있다. 전반적으로 노드 이벤트 핸들러 방식을 따르고 있다고 보면 된다.
// 해당 이벤트를 받고 콜백함수를 실행
socket.on('받을 이벤트 명', (msg) => {
})
// 이벤트 명을 지정하고 메세지를 보낸다.
socket.emit('전송할 이벤트 명', msg)
이런식으로 메세지 마다 고유한 이벤트를 등록해 구별해서 송수신하면, 채팅방에서 '귓속말'기능처럼 특정 어느 사람에게만 메세지를 송신한다던지 등 다양한 통신 기능을 구현할 수 있다.
소켓 메세지 수신
// 접속된 모든 클라이언트에게 메세지를 전송한다
io.emit('event_name', msg);
// 메세지를 전송한 클라이언트에게만 메세지를 전송한다.
socket.emit('event_name', msg);
// 메세지를 전송한 클라이언트를 제외한 모든 클라이언트에게 메세지를 전송
socekt.broadcast.emit('event_name', msg);
// 특정 클라이언트에게만 메세지를 전송한다.
io.to(id).emit('event_name', data);
소켓 메세지 송신
// 클라이언트와 소켓io 연결됐는지 안됐는지 이벤트 실행
io.on('connection/disconnection', (socket) => {
});
// 클라이언트에서 지정한 이벤트가 emit 되면 수신 발생
socekt.on('event_name', (data) => {
});
소켓io에 서버 정보 넘겨주고 구동, 이벤트 통신
// index.js
import express from 'express';
import { createServer } from 'node:http';
import { configDotenv } from 'dotenv';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { Server } from 'socket.io';
const app = express();
const server = createServer(app);
const io = new Server(server);
const __dirname = dirname(fileURLToPath(import.meta.url));
configDotenv();
app.get('/', (req, res) => {
res.sendFile(join(__dirname, 'index.html'));
});
io.on('connection', (socket) => {
const req = socket.request;
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
console.log(`${socket.id} 님이 접속하셨습니다!`);
socket.on('chat message', (msg) => {
console.log(`${socket.id}: ` + msg);
io.emit('chat message', msg);
});
});
server.listen(process.env.SERVER_PORT, () => {
console.log(`server running at ${process.env.SERVER_PORT}`);
});
// index.html
<script src="/socket.io/socket.io.js"></script>
socket.io 모듈은 내부적으로 "루트/socket.io" 경로에 socket.io.js 파일을 자동으로 등록해둔다.
// index.html
<script>
const socket = io();
const form = document.getElementById('form');
const input = document.getElementById('input');
const messages = document.getElementById('messages')
form.addEventListener('submit', (e) => {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
// 서버로부터 메세지 수신
socket.on('chat message', (msg) => {
const item = document.createElement('li');
item.textContent = msg;
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
</script>