Socket.io 채팅 예제: Node.js 실시간 채팅 만들기
Socket.io를 사용해 단계별로 실시간 채팅 서버와 클라이언트를 구현하고 핵심 개념, 예제 코드, 보안 및 배포 유의사항을 정리한 개발 자료
목차
개요
이 글은 Socket.io로 간단한 실시간 채팅 서비스를 만드는 과정을 처음 접하는 사람도 이해하기 쉽게 설명한다. 핵심 개념을 짚고 직접 실행 가능한 서버·클라이언트 예제를 제공한다. 또한 배포와 보안 관련 기본 유의사항도 다룬다. 주요 키워드: Socket.io 채팅 예제, Node.js 실시간 채팅 만들기, Socket.io 튜토리얼.
사전 준비
필수 항목
- Node.js 최신 LTS 버전
- npm 또는 yarn
- 간단한 JavaScript 및 HTML 지식
프로젝트 구조
간단한 예제로 다음 구조를 사용한다.
- server.js — Node.js 서버
- public/index.html — 클라이언트 HTML
- public/client.js — 클라이언트 소켓 로직
설치
터미널에서 프로젝트 폴더를 만들고 express와 socket.io를 설치한다.
- npm init -y
- npm install express socket.io
서버 코드 (Node.js)
서버는 HTTP 서버를 만들고 Socket.io를 연결해 클라이언트 메시지를 브로드캐스트한다. 아래 예제는 연결, 메시지 수신, 연결 해제 이벤트를 다룬다.
const express = require('express')
const http = require('http')
const { Server } = require('socket.io')
const app = express()
const server = http.createServer(app)
const io = new Server(server)
app.use(express.static('public'))
io.on('connection', (socket) => {
console.log('사용자 연결:', socket.id)
socket.on('join', (username) => {
socket.username = username
socket.broadcast.emit('system message', `${username}님이 입장했습니다.`)
})
socket.on('chat message', (msg) => {
const payload = { id: socket.id, user: socket.username || '익명', message: msg, time: Date.now() }
io.emit('chat message', payload)
})
socket.on('disconnect', () => {
if (socket.username) {
socket.broadcast.emit('system message', `${socket.username}님이 나갔습니다.`)
}
console.log('사용자 연결 해제:', socket.id)
})
})
const PORT = process.env.PORT || 3000
server.listen(PORT, () => console.log(`서버 실행: http://localhost:${PORT}`))
클라이언트 코드
클라이언트는 Socket.io 클라이언트 라이브러리를 사용해 서버에 연결하고 메시지를 주고받는다. 아래 HTML은 간단한 UI와 클라이언트 로직을 포함한다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Socket.io 채팅 예제</title>
</head>
<body>
<div id="chat">
<div id="messages"></div>
<input id="username" placeholder="이름" />
<input id="input" autocomplete="off" />
<button id="send">전송</button>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io()
const messages = document.getElementById('messages')
const input = document.getElementById('input')
const sendBtn = document.getElementById('send')
const usernameInput = document.getElementById('username')
sendBtn.addEventListener('click', () => {
const name = usernameInput.value || '익명'
socket.emit('join', name)
if (input.value) {
socket.emit('chat message', input.value)
input.value = ''
}
})
socket.on('chat message', (data) => {
const el = document.createElement('div')
el.textContent = `${data.user}: ${data.message}`
messages.appendChild(el)
})
socket.on('system message', (txt) => {
const el = document.createElement('div')
el.style.fontStyle = 'italic'
el.textContent = txt
messages.appendChild(el)
})
</script>
</body>
</html>
기능 확장 아이디어
- 채팅방 분리(Rooms) - io.to(room).emit으로 특정 방에만 전송
- 접속자 목록 관리 - 서버에서 소켓별 이름 저장
- 타이핑 표시 - typing 이벤트로 실시간 입력 상태 전달
- 메시지 저장 - 데이터베이스에 기록해 채팅 내역 제공
테스트와 배포
로컬에서 테스트할 때는 브라우저 여러 탭을 열어 동작을 확인한다. 실제 배포 시는 Nginx 같은 리버스 프록시를 사용하거나 클라우드 플랫폼(예: Heroku, AWS Elastic Beanstalk)에 배포한다. WebSocket 연결이 프록시에서 허용되는지 확인해야 한다.
보안과 운영 고려사항
- 입력 값 검증으로 XSS 위험 최소화
- 인증이 필요한 서비스는 Socket.io 연결 시 토큰 검증 수행
- 속도 제한(rate limiting)과 메시지 길이 제한 적용
- TLS 적용으로 통신 암호화
문제 해결 팁
- 클라이언트가 연결되지 않으면 브라우저 콘솔과 서버 로그를 확인
- 프록시 설정 시 upgrade 헤더가 전달되는지 점검
- 버전 호환성 문제 발생 시 socket.io 버전 확인
정리
이 글에서는 Socket.io 채팅 예제와 Node.js 실시간 채팅 만들기 과정을 차근차근 다루었다. 간단한 서버·클라이언트 예제를 통해 연결, 메시지 브로드캐스트, 기본 보안 고려사항을 확인할 수 있다. 이후에는 방 기능, 인증, 메시지 저장 등을 차례로 추가하며 확장하면 실무 수준의 채팅 서비스를 완성할 수 있다.