NestJS와 Socket.io를 활용한 실시간 1대1 랜덤 채팅 애플리케이션입니다.
WebSocket을 적용해 본 경험이 없는 것 같아서, 학습을 위해 WebSocket 기반 양방향 통신, JWT 인증, 자동 매칭 시스템, 실시간 메시지 저장 등의 기능을 구현해보았습니다.
- NestJS에서 WebSocket을 활용한 실시간 통신 구현
- Socket.io와 NestJS Gateway 패턴 학습
- JWT 기반 WebSocket 인증 처리
- 1대1 자동 매칭 알고리즘 구현
- 실시간 메시지를 DB에 영구 저장
- 외의 객체지향, 테스트 작성에 중점
- 실시간 양방향 통신: Socket.io 기반 WebSocket
- 자동 매칭 시스템: 대기열 기반 선착순 매칭
- JWT 인증: WebSocket 연결 시 토큰 검증
- 메시지 영구 저장: PostgreSQL을 통한 채팅 이력 관리
- 중복 연결 방지: 같은 사용자의 여러 탭 접속 시 자동 처리
- Framework: NestJS 10.x
- Language: TypeScript 5.x
- WebSocket: Socket.io 4.x
- Database: PostgreSQL 16.x
- ORM: Prisma 6.x
- Authentication: JWT (jsonwebtoken, @nestjs/jwt)
- HTML5, Vanilla JavaScript
- Socket.io Client CDN
- Package Manager: pnpm
- Code Quality: ESLint, Prettier
- Testing: Jest
- JWT 기반 WebSocket 인증
- 연결 시 자동 입장 처리
- 중복 연결 감지 및 기존 연결 종료
- 연결 해제 시 자동 정리 (매칭 취소, 채팅방 종료)
- 매칭 대기열 관리 (Memory Level, FIFO)
- 2명 모이면 자동 매칭
- 매칭 시 채팅방 자동 생성 (DB 저장)
- 매칭 성공 시 상대방 정보 전달
- 1대1 실시간 메시지 송수신
- 메시지 DB 영구 저장
- 채팅방 나가기
- 상대방 나감 알림
- 메시지 유효성 검증
prisma-markdown을 활용하여 문서를 작성했습니다.
.env 파일 생성
# 데이터베이스
DATABASE_URL="postgresql://user:password@localhost:5432/chatdb"
# JWT
JWT_SECRET="your-secret-key-change-this"
JWT_EXPIRES_IN="1d"
# 서버
PORT=9090
NODE_ENV=developmentpnpm install# Prisma 마이그레이션
pnpm prisma migrate dev
# Prisma Client 생성
pnpm prisma generate# 개발 모드
pnpm start:dev
# 프로덕션 빌드
pnpm build
pnpm start:prod- API: http://localhost:9090
- Swagger: http://localhost:9090/api-docs
- 테스트 클라이언트: http://localhost:9090/index.html
- HTTP와 다르게 WebSocket은 초기 연결 수립만 진행하고 양방향 실시간 통신 지원 프로토콜.
- Socket.io는 Node 진영에서 WebSocket 프로토콜을 쉽게 구현할 수 있도록 도와주는 라이브러리.
- WebSocket에서의 LifeCycle Hook (OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect)
- 외에 다양하게 사용되는 이벤트 핸들러, 데코레이터 등
- 유니캐스트와 브로드캐스트
- 메모리 기반 상태 관리
- 대기열 자료구조 (FIFO Queue)
- 매칭 로직 분리
- 실시간 통신과 DB 저장의 분리
- 비동기 처리 (async/await)
- 에러 처리 (DB 저장 실패 시에도 실시간 전송 계속)
- 학습을 위한 프로젝트이지만, 실환경을 고려해서 심화 학습을 해보려고 합니다.
Claude의 도움을 받아 작성하게 되었습니다.
문제점:
- 현재 매칭 큐와 연결 정보가 메모리에 저장
- 서버 재시작 시 데이터 손실
- 다중 서버 배포 불가능
개선 방안:
✅ Socket.io Redis Adapter 적용
✅ 매칭 큐를 Redis List/Set으로 관리
✅ 연결 정보를 Redis Hash로 저장
✅ Redis Pub/Sub으로 서버 간 통신
학습 효과:
- 분산 시스템 아키텍처 이해
- Redis 실전 활용
- 수평 확장 (Scale-out) 경험
문제점:
- 동시 매칭 요청 시 중복 매칭 가능
- Race Condition
개선 방안:
✅ Redis 분산 락 (Redlock) 구현
✅ 매칭 프로세스에 락 적용
✅ 메시지 Sequence Number 추가
✅ DB Optimistic Locking
학습 효과:
- 동시성 문제 해결 능력
- 분산 락 개념 및 구현
- 실무 버그 패턴 이해
✅ 메시지 배치 처리 (Bull Queue)
✅ Redis 캐싱 (유저 정보, 채팅방)
✅ DB 인덱스 최적화
✅ Connection Pool 튜닝
✅ Rate Limiting (메시지 스팸 방지)
✅ XSS 방지 (메시지 sanitization)
✅ CORS 정책 강화
✅ 재연결 처리 (Reconnection)
✅ Unit Test (Jest)
✅ E2E Test (WebSocket)
✅ 부하 테스트 (Artillery.io)
이 프로젝트를 통해 다음을 학습했습니다:
- ✅ NestJS에서 WebSocket 구현하는 방법
- ✅ Socket.io의 핵심 개념 (Room, Emit, Broadcast)
- ✅ WebSocket JWT 인증 처리
- ✅ 실시간 매칭 알고리즘 설계
- ✅ 실시간 데이터와 영구 저장소의 조화
- ✅ 클린 아키텍처 적용 (Layer 분리)