Nodejs
[Node.js] Socket.IO를 사용한 웹 채팅 만들기
teamnova
2025. 2. 24. 21:39
728x90
이번에는 Socket.IO를 사용한 간단한 채팅을 만들어 보겠습니다.
Socket.IO를 사용하면 웹소켓을 쉽게 구현이 가능합니다. 클라이언트와 서버간의 통신이 가능합니다.
- 왜 이 코드를 사용할까?
- 실시간 채팅 구현이 간편함 → Socket.IO를 사용하면 복잡한 웹소켓 프로토콜을 신경 쓰지 않고도 채팅 기능을 쉽게 구축할 수 있음.
- 빠른 데이터 전송 가능 → 서버와 클라이언트가 이벤트 기반으로 데이터를 주고받음 -> 채팅이 가능.
- Node.js의 비동기 처리 → 대량의 동시 접속자를 처리하기에 적합.
- 어디에 활용하면 좋을까?
- 기본적인 채팅 애플리케이션 → 익명 채팅, 고객 문의 챗봇, 커뮤니티 채팅 등에 활용 가능.
- 실시간 알림 시스템 → 사용자에게 실시간 알림을 보내는 기능에 응용 가능.
- 멀티 유저 협업 도구 → 실시간 공동 편집, 화상 회의 채팅 기능 등에 적용 가능.
터미널에서 초기화 및 필요한 패키지 설치
npm init -y npm
install express socket.io
index.html
<!-- HTML5 문서임을 선언. 최신 표준으로 브라우저가 인식 -->
<!DOCTYPE html>
<!-- HTML 문서의 시작. lang 속성은 생략했지만 기본적으로 영어로 간주 -->
<html>
<head>
<!-- 페이지 제목. 브라우저 탭에 표시 -->
<title>실시간 채팅</title>
<!-- CSS 스타일을 정의. 페이지 모양 꾸밈 -->
<style>
/* body 요소의 글꼴을 Arial로 설정. */
body { font-family: Arial, sans-serif; }
/* 메시지 목록의 스타일. 기본 목록 점을 없애고 여백을 조정 */
#messages { list-style-type: none; padding: 0; }
/* 각 메시지 항목에 여백을 줘서 보기 좋게함함 */
#messages li { padding: 5px; }
</style>
</head>
<body>
<!-- 메시지가 표시될 unordered list. 채팅 내용을 담는 공간 -->
<ul id="messages"></ul>
<!-- 메시지 입력 폼. 사용자가 텍스트를 입력하고 전송 -->
<form id="form" action="">
<!-- 텍스트 입력 필드. autocomplete 끄고, ID로 쉽게 접근 가능 -->
<input id="input" autocomplete="off" />
<!-- 전송 버튼. 클릭하면 폼이 제출출 -->
<button>전송</button>
</form>
<!-- Socket.IO 클라이언트 스크립트를 서버에서 가져옴. 실시간 통신의 핵심 -->
<script src="/socket.io/socket.io.js"></script>
<!-- 클라이언트 측 JavaScript 코드 시작 -->
<script>
// 사용자에게 이름 입력창을 띄우고 입력값을 저장. 채팅에서 사용할 닉네임
const username = prompt('채팅에서 사용할 이름을 입력하세요:');
// Socket.IO로 서버와 연결 시작. 실시간 통신을 위한 소켓 객체를 만듬듬
const socket = io();
// 서버에 'user joined' 이벤트를 보내 유저 이름을 전달. 입장 처리 시작
socket.emit('user joined', username);
// HTML에서 form 요소를 가져옴. 메시지 전송을 처리
const form = document.getElementById('form');
// 입력 필드를 가져옴. 사용자가 메시지를 입력하는 곳
const input = document.getElementById('input');
// 메시지 목록을 가져옴. 새 메시지를 여기 추가
const messages = document.getElementById('messages');
// 폼 제출 이벤트 리스너 추가. 메시지를 보내는 트리거
form.addEventListener('submit', (e) => {
// 기본 폼 제출 동작(페이지 새로고침)을 막음. 실시간 앱에선 필요 없음
e.preventDefault();
// 입력값이 비어있지 않으면 실행
if (input.value) {
// 서버에 'chat message' 이벤트로 이름과 메시지를 보냄
socket.emit('chat message', { username, message: input.value });
// 입력 필드를 비움. 다음 메시지를 위해 준비
input.value = '';
}
});
// 서버에서 'chat message' 이벤트를 받으면 실행. 새 메시지를 표시
socket.on('chat message', (data) => {
// 새로운 li 요소를 만듦. 메시지를 담을 공간
const li = document.createElement('li');
// 메시지 형식으로 텍스트 설정. "이름: 메시지" 형태
li.textContent = `${data.username}: ${data.message}`;
// 메시지 목록에 새 li를 추가. 채팅창에 메시지 나타남
messages.appendChild(li);
});
</script>
</body>
</html>
server.js
// Express 모듈을 가져옴. 웹 서버를 쉽게 만들 수 있게 도와주는 프레임워크.
const express = require('express');
// Node.js 기본 모듈인 http를 가져옴. 웹 서버를 직접 만들 때 필요요.
const http = require('http');
// Socket.IO 모듈에서 Server 클래스를 가져옴. 실시간 통신을 위해 사용.
const { Server } = require('socket.io');
// 경로 처리를 쉽게 해주는 Node.js 기본 모듈.
const path = require('path');
// Express 앱을 생성. 이걸로 웹 요청을 처리.
const app = express();
// Express 앱을 기반으로 HTTP 서버를 만듦. Socket.IO가 이 서버 위에서 동작.
const server = http.createServer(app);
// Socket.IO 서버를 만듦. 실시간 양방향 통신을 가능.
const io = new Server(server);
// 서버가 사용할 포트 번호를 3000으로 설정. 브라우저에서 접속할 때 이 번호를 사용.
const port = 3000;
// '/' 경로로 GET 요청이 오면 index.html 파일을 클라이언트에게 보냄. 채팅 UI를 보여주는 기본 페이지.
app.get('/', (req, res) => {
// __dirname은 현재 파일의 경로를 뜻하고, path.join으로 index.html 파일 경로를 안전하게.
res.sendFile(path.join(__dirname, 'index.html'));
});
// 클라이언트가 소켓으로 연결되면 이 코드가 실행.
io.on('connection', (socket) => {
// 새로운 사용자가 접속했음을 서버 콘솔에 출력. 디버깅이나 상태 확인.
console.log('새로운 사용자가 연결되었습니다!');
// 클라이언트가 'user joined' 이벤트를 보내면 실행. 유저 이름을 받아 처리.
socket.on('user joined', (username) => {
// 현재 소켓에 유저 이름을 저장. 나중에 퇴장할 때 사용용.
socket.username = username;
// 서버 콘솔에 누가 입장했는지 출력. 어떤 유저가 들어왔는지 확.
console.log(`${username}님이 입장했습니다!`);
// 모든 클라이언트에게 시스템 메시지로 입장 알림을 보냄. 채팅창에 표시.
io.emit('chat message', { username: '시스템', message: `${username}님이 입장했습니다!` });
});
// 클라이언트가 'chat message' 이벤트를 보내면 실행. 채팅 메시지를 받아 처리.
socket.on('chat message', (data) => {
// 서버 콘솔에 누가 어떤 메시지를 보냈는지 출력. 로그로 남겨서 확인 가능.
console.log(`${data.username}: ${data.message}`);
// 모든 클라이언트에게 받은 메시지를 그대로 전달. 실시간 채팅이 가능.
io.emit('chat message', { username: data.username, message: data.message });
});
// 클라이언트가 연결을 끊으면 실행. 접속 종료를 감지.
socket.on('disconnect', () => {
// 서버 콘솔에 누가 나갔는지 출력. username이 없으면 '익명'으로 표시.
console.log(`${socket.username || '익명'}님이 연결을 끊었습니다.`);
// 모든 클라이언트에게 시스템 메시지로 퇴장 알림을 보냄. 채팅창에 표시.
io.emit('chat message', { username: '시스템', message: `${socket.username || '익명'}님이 퇴장했습니다!` });
});
});
// 서버를 포트 3000에서 실행 시작. 성공하면 콘솔에 메시지를 띄움.
server.listen(port, () => {
// 서버가 잘 시작됐는지 확인하기 위해 콘솔에 출력. URL도 알림림.
console.log(`서버가 http://localhost:${port}에서 실행 중입니다!`);
});
터미널에서 node server.js 입력 후 실행
시연영상