@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
/* 클라이언트가 최초로 WebSocket 연결을 시도할 때 접속할 `엔드포인트` 설정 */
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// `/ws` : 서버 내부 엔드포인트 경로
// CORS 설정 + SockJS 프로토콜 지원 추가 (fallback)
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
}
/* STOMP 메시지 라우팅 규칙 설정
* 서버와 클라이언트가 메시지를 주고받을 때 `어떤 경로로 처리할지` 정의
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 클라이언트 --> 서버 prefix
// ex) /pub/chatroom.create
// @MessageMapping("chatroom.create") 으로 매핑됨
registry.setApplicationDestinationPrefixes("/pub");
// 서버 --> 클라이언트로 메시지 broadcasting 시 사용할 prefix
// ex) /sub/chatroom/created
// @SendTo("/sub/chatroom/created") 으로 클라이언트 구독 가능
registry.enableSimpleBroker("/sub");
}
}
Spring에서 WebSocket + STOMP 프로토콜을 통한 pub/sub 메시징 기능 활성화하는 어노테이션
👉 @Configuration
클래스에서 사용
👉 WebSocket을 통한 메시지 처리 기능을 활성화
👉 STOMP (Simple Text Oriented Messaging Protocol) 같은 프로토콜을 사용한 pub/sub (발행/구독) 방식의 통신을 지원
1️⃣ 클라이언트(웹 브라우저 등)가 /ws 엔드포인트로 WebSocket 연결 요청
2️⃣ STOMP 프로토콜 기반으로 메시지 주고받기 시작
3️⃣ 서버는 /app/**
경로로 들어오는 메시지 처리
4️⃣ 서버는 /topic/**
경로로 메시지 브로드캐스팅
팁 1: @EnableWebSocketMessageBroker
는 "WebSocket을 직접 구현"하는 게 아니라, "메시지 브로커 기반으로 WebSocket을 쉽게 구성"할 수 있게 도와주는 고수준(high-level) 설정이에요.
팁 2: @EnableWebSocket
라는 것도 있는데, 이건 좀 더 "저수준 WebSocket 핸들러"를 만들 때 사용 (STOMP 기반 X). 보통 실시간 채팅 서비스 등에서는 @EnableWebSocketMessageBroker
가 더 편리합니다.
팁 3: SockJS
를 사용하면 WebSocket이 안 되는 환경(구형 브라우저 등)에서도 fallback 지원 가능!
STOMP (Simple Text Oriented Messaging Protocol)
- WebSocket 위에서 동작하는 메시지 프로토콜
- WebSocket은 그냥 "소켓 연결"만 해줌 → 메시지 구분이 안 됨
- STOMP는 → 메시지에 "주소(경로)" 를 붙여서 → 서버가 어떤 메서드에서 처리할지 알 수 있게 함!
쉽게 말해:
HTTP에서 URL로 "어디 요청할지" 정하는 것처럼,
STOMP에서는 "destination" (목적지 주소) 로 메시지 "라우팅" 함
SEND
destination:/pub/chatroom.create
content-type:application/json
{"roomName": "myroom"}
필드 | 설명 |
---|---|
SEND | 클라이언트 → 서버로 메시지 보냄 |
destination | 어디로 보낼지 주소 (→ 이게 "라우팅" 주소) |
본문 | 실제 데이터 |
destination 경로를 기반으로
→ 서버의 어떤 메서드(@MessageMapping)에 매핑할지 결정하는 과정
STOMP destination | 서버 쪽 처리 위치 |
---|---|
/pub/chatroom.create | @MessageMapping("chatroom.create") |
/pub/chat.send | @MessageMapping("chat.send") |
destination 주소 ↔ 서버 메서드 연결 → "라우팅"