WebSocket = 실시간으로 연결해주는 통신 통로
STOMP = 그 통로에서 메시지를 어떻게 보내고 받을지 정해주는 규칙
1. 왜 라이브러리가 달라질까?
- 백엔드에서 어떤 WebSocket 기술을 사용하는지에 따라 프론트에서 사용하는 라이브러리도 달라진다.
- 이번 프로젝트에서는 Spring WebSocket + STOMP를 사용했기 때문에 프론트에서도 STOMP 프로토콜을 지원하는 @stomp/stompjs를 사용했다.
2. 전체 구조
@stomp/stompjs(프론트) ◀── WebSocket + STOMP ──▶ Spring WebSocket(백엔드)
- WebSocket → 연결 유지
- STOMP → 메시지 규칙
- Spring → 메시지 처리
- StompJS → STOMP를 사용할 수 있게 해주는 라이브러리
3. WebSocket만으로 부족한 이유
- WebSocket은 클라이언트와 서버가 연결을 유지하면서 양방향으로 데이터를 주고받을 수 있게 해주는 프로토콜이다.
- 클라이언트 ◀════════▶ 서버 = 연결 유지
- 하지만 WebSocket만으로는 메시지를 어디로 보내고, 어떤 사용자가 받아야 하는지와 같은 규칙이 없다.
- 메시지를 어느 채팅방으로 보낼지
- 어떤 메시지를 구독할지
- 메시지의 목적지를 어떻게 표현할지
- 메시지 종류를 어떻게 구분할지
- 메시지 수신을 어떻게 확인할지
- 그래서 Spring에서는 이러한 메시지 규칙을 정의하기 위해 STOMP 프로토콜을 함께 사용한다.
- WebSocket
→ 연결
- STOMP
→ 메시지 규칙
4. STOMP란?
- STOMP는 CONNECT, SUBSCRIBE, SEND, MESSAGE와 같은 명령을 통해 메시지를 주고받는 프로토콜이다.
- 이번 글에서는 연결에 필요한 정도만 다루고, STOMP의 명령과 메시지 구조는 다음 글에서 자세히 정리할 예정이다.
5. 왜 Socket.IO를 사용하지 않을까?
- Socket.IO도 실시간 양방향 통신을 편리하게 구현할 수 있는 라이브러리다.
- 하지만 백엔드가 Spring WebSocket + STOMP 방식으로 구현되어 있다면 프론트도 STOMP를 이해하는 클라이언트를 사용해야 한다.
- Socket.IO 클라이언트 → Spring WebSocket + STOMP 서버 => ❌
- STOMP 클라이언트 → Spring WebSocket + STOMP 서버 => ✅
6. 프론트엔드 패키지 설치
- 순수 WebSocket + STOMP를 사용한다면 다음 패키지를 설치한다.
npm install @stomp/stompjs
- REST API 요청에 Axios도 사용한다면 함께 설치할 수 있다.
npm install axios @stomp/stompjs
- axios
- 로그인, 채팅 내역 조회 등 HTTP API 요청
- @stomp/stompjs
- WebSocket 연결 및 STOMP 메시지 처리
7. STOMP 서버 연결하기
- 프론트에서는 Client 객체를 생성해 Spring WebSocket 서버에 연결한다.
import { Client } from "@stomp/stompjs";
const stompClient = new Client({
brokerURL: "wss://api.example.com/ws",
connectHeaders: {
Authorization: `Bearer ${accessToken}`,
},
reconnectDelay: 5000,
onConnect: () => {
console.log("STOMP 연결 성공");
},
onStompError: (frame) => {
console.error("STOMP 오류:", frame.headers.message);
console.error("상세 내용:", frame.body);
},
onWebSocketError: (error) => {
console.error("WebSocket 오류:", error);
},
});
stompClient.activate();
- brokerURL : WebSocket 서버의 연결 주소
- brokerURL: "wss://api.example.com/ws";
- 개발 환경에서는 ws://, HTTPS를 사용하는 운영 환경에서는 암호화된 wss://를 사용한다.
- connectHeaders : STOMP 연결 시 서버에 전달할 헤더
- JWT를 어떻게 전달할지는 백엔드의 인증 구현에 따라 달라질 수 있으므로 백엔드 개발자와 명세를 맞춰야 한다.
- reconnectDelay : 연결이 끊어진 경우 자동 재연결을 시도할 간격이다.
- reconnectDelay: 500