https://nippyclouding.tistory.com/51
[Spring] 웹소켓/Stomp 5
https://nippyclouding.tistory.com/49 [Spring] 웹소켓/Stomp 4Stomp는 순수 웹소켓과 다르게 각 room (주로 topic이라고 호칭)들을 구분하여 관리할 수 있다. (사용자마다 group화 되어있다)순수 웹소켓도 각 room을
nippyclouding.tistory.com
위와 이어진다.
EventListener
- Stomp에서는 순수 웹소켓과 다르게 직접 클라이언트 세션들을 개발자가 관리하지 않는다.
- 클라이언트 세션들은 Stomp에서 자동으로 편리하게 관리하고 있다.
- 웹소켓을 이용하며 발생한 사건(event)들을 catch하여 기록, 로깅할 수 있도록 돕는 객체가 EventListener이다.
- 웹소켓 시스템의 기록 일지 역할
- 1:1 채팅이 아닌 단체 채팅의 경우 여러 사용자 세션들이 서버와 연결을 맺기 때문에 서버 부하를 고려하여 최대 인원 수가 지정되어 있다.
- 사용자가 웹소켓 연결을 일방적으로 끊거나, 새로운 웹소켓 연결이 들어올 경우에 대비해 세밀한 제어를 하기 위해 이벤트 리스너가 존재한다.
웹소켓에서 Stomp EventListener은 HTTP와 달리 '연결'과 '종료'라는 상태 변화가 명확한 웹소켓의 특성을 관리하기 위해 존재한다.
인터셉터(StompHandler)가 입구에서 토큰을 검사하는 문지기라면, 리스너는 이미 벌어진 일을 기록하는 관찰자이다.
HTTP는 응답 후 연결을 바로 끊는 비연결성(Stateless) 때문에, 웹소켓처럼 실시간 연결 상태를 추적하는 이벤트 리스너 개념이 없다.
이벤트 리스너를 활용해야 사용자가 메시지를 보내지 않고 브라우저만 닫았을 때도 이탈을 감지해 정확한 접속자 관리가 가능하다.
이 구조는 스프링의 AOP처럼 보안(인터셉터), 비즈니스(컨트롤러), 상태관리(리스너)를 분리하여 코드의 유지보수성을 향상시키는 것에 기여한다.

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectEvent;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
public class StompEventListener {
private final Set<String> set = ConcurrentHashMap.newKeySet();
@EventListener
public void connectHandle(SessionConnectEvent event) {
// SessionConnectEvent : 커넥션이 발생했을 때 이벤트 리스너의 connectHandle가 동작한다.
StompHeaderAccessor wrap = StompHeaderAccessor.wrap(event.getMessage());
set.add(wrap.getSessionId());
log.info("connect session Id : {}", wrap.getSessionId());
log.info("total session set : {}", set.size());
}
@EventListener
public void disconnectHandle(SessionDisconnectEvent event) {
// SessionDisconnectEvent : 커넥션이 종료되었을 때 이벤트 리스너의 disconnectHandle가 동작한다.
StompHeaderAccessor wrap = StompHeaderAccessor.wrap(event.getMessage());
set.remove(wrap.getSessionId());
log.info("disconnect session Id : {}", wrap.getSessionId());
log.info("total session set : {}", set.size());
}
}
'Java & Spring > WebSocket & Stomp' 카테고리의 다른 글
| [Spring] 웹소켓/Stomp 8 (0) | 2026.02.28 |
|---|---|
| [Spring] 웹소켓/Stomp 7 (0) | 2026.02.18 |
| [Spring] 웹소켓/Stomp 5 (0) | 2026.02.17 |
| [Spring] 웹소켓/Stomp 4 (0) | 2026.02.16 |
| [Spring] 웹소켓/Stomp 3 (0) | 2026.02.16 |