클라이언트에서 웹소켓 연결 이후 아무 동작도 하지 않으면 20~30초 후에 에러가 발생하면서 연결이 끊김

2025-08-19T15:14:25.729+09:00 ERROR 31340 --- [ezcode] [ent-scheduler-5] o.s.m.s.s.StompBrokerRelayMessageHandler : Received ERROR {message=[AMQ229014: Did not receive data from 39.119.68.26:4696 within the 20000ms connection TTL. The connection will now be closed.]} session=l4xbygd2, user=test@test.com
2025-08-19T15:14:33.730+09:00 ERROR 31340 --- [ezcode] [ent-scheduler-7] o.s.m.s.s.StompBrokerRelayMessageHandler : Received ERROR {message=[AMQ229014: Did not receive data from 39.119.68.26:4698 within the 40000ms connection TTL. The connection will now be closed.]} session=dy1m111s, user=test@test.com
org.ezcode.codetest.domain.chat.exception.ChattingException: 해당 채팅 세션이 조회되지 않습니다.
at org.ezcode.codetest.infrastructure.session.service.RedisSessionCountService.removeSessionCount(RedisSessionCountService.java:125) ~[main/:na]
at org.ezcode.codetest.infrastructure.event.listener.WebSocketEventListener.onApplicationEvent(WebSocketEventListener.java:54) ~[main/:na]
at org.ezcode.codetest.infrastructure.event.listener.WebSocketEventListener.onApplicationEvent(WebSocketEventListener.java:21) ~[main/:na]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185) ~[spring-context-6.2.7.jar:6.2.7]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-6.2.7.jar:6.2.7]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156) ~[spring-context-6.2.7.jar:6.2.7]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:454) ~[spring-context-6.2.7.jar:6.2.7]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:387) ~[spring-context-6.2.7.jar:6.2.7]
하트비트 옵션을 다시 활성화 하면 간단하게 해결 가능
수동으로 가짜 트래픽을 발생시켜 연결이 살아있음을 ActiveMQ에게 주기적으로 알려줘야 함
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class StompKeepAliveScheduler {
private final SimpMessagingTemplate messagingTemplate;
public StompKeepAliveScheduler(SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
// 15초마다 실행 (ActiveMQ TTL인 20초보다 짧게 설정)
@Scheduled(fixedDelay = 15000)
public void sendKeepAliveMessage() {
this.messagingTemplate.convertAndSend("/topic/keep-alive", "ping");
}
}