@EnableWebSocketMessageBroker
이걸 붙이면 Spring은 다음을 해줘:
- WebSocket 서버 역할을 수행할 준비 완료
STOMP 프로토콜을 이용한 pub/sub 메시지 처리 구조를 구성
WebSocketMessageBrokerConfigurer 구현체를 찾아서 실행
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOriginPatterns("*")
.withSockJS();
}
- registry.addEndpoint("/ws")
클라이언트가 웹소켓을 연결하려는 진입점을 /ws로 설정
→ 즉, JS 코드에서 new SockJS("/ws") 또는 new WebSocket("/ws") 식으로 접근함
- .setAllowedOriginPatterns("")
모든 도메인(origin)에서 이 엔드포인트에 접근 가능하게 허용 (CORS 설정)
→ 실제 운영에서는 "" 대신 특정 도메인만 허용하는 게 보안상 안전함
- .withSockJS();
SockJS를 활성화해서 웹소켓을 지원하지 않는 브라우저에서도 fallback(대체) 방식으로 통신 가능하게 함
(예: 오래된 IE 브라우저에서 Ajax long-polling으로 동작)
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/sub");
registry.setApplicationDestinationPrefixes("/pub");
}
👉 클라이언트가 서버에게 메시지를 보낼 때의 주소 접두어
즉, JS에서 stompClient.send("/pub/~~~")로 보내면 그건 서버 컨트롤러의 @MessageMapping("/~~~")으로 매핑됨
stompClient.send("/pub/chat/message", {}, JSON.stringify({...}))
===
@MessageMapping("/chat/message")
public void send(ChatMessage message) {
// 여기로 연결됨
}
👉 서버가 클라이언트에게 메시지를 보낼 때 사용하는 경로 접두어
즉, 서버에서 convertAndSend("/sub/~~~")로 메시지를 보내면 클라이언트는 stompClient.subscribe("/sub/~~~")로 구독 가능
stompClient.subscribe("/sub/chat/room/1", (msg) => {
console.log("받은 메시지", msg.body);
});
✅ 클라이언트가 서버에게 "메시지를 보내는(pub)" 용도야.
@MessageMapping("/chat/{chatroomId}/message")
이건 클라이언트가 /pub/chat/1/message로 send 하면 동작하는 로직
그래서 "받는 것처럼 보이지만 실제론 요청 핸들링"이야
| 항목 | 설명 |
|---|---|
@MessageMapping("/chat/{chatroomId}/message") | 클라이언트가 서버에게 보내는 경로 → pub |
stompClient.send("/pub/chat/1/message", ...) | 클라이언트 → 서버 메시지 전송 |
messagingTemplate.convertAndSend("/sub/chat/room/1", ...) | 서버 → 모든 구독자(클라이언트)에게 메시지 push |
stompClient.subscribe("/sub/chat/room/1") | 클라이언트가 실시간 수신하고 싶은 경로 등록 |
const socket = new SockJS("/ws"); // ← 소켓 연결 요청
const stompClient = Stomp.over(socket);
stompClient.connect({}, () => {
console.log("WebSocket 연결 완료"); // ← 서버가 수락하면 연결 성립
});
브라우저(클라이언트)가 /ws 엔드포인트로 handshake 요청을 보내고
서버(Spring)가 이걸 받아서 WebSocket 연결을 수락하는 구조야.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws") // ← 프론트가 연결 요청할 경로
.setAllowedOriginPatterns("*")
.withSockJS();
}
}
서버는 /ws로 연결 요청이 오면 "오케이 연결하자" 하고 수락만 해주는 거야.