웹 소켓이 끊기는데 백엔드 로그에 disconnect가 안 남고 client에서의 재 연결 로직도 10분 정도 후에 타서 지속적으로 이슈가 올라왔음
서버에서 클라이언트에게 보내는 하트비트가 갑자기 멈춤
OS level의 리눅스 커널에서는 오래 사용되지 않은 TCP connection에 Keep-Alive 패킷을 보내 해당 connection을 끊을지 결정한다고 함
하트비트가 끊긴 시점에 주기적으로 TCP Keep-Alive 패킷을 전송하고 있었고 최대 횟수 보내자마자 해당 TCP connection을 끊는 패킷이 전송됨(FIN, ACK)
그제서야 클라이언트는 웹소켓에 대한 TCP connection 끊김을 감지하고 재 연결 시도
stomp level heartbeat는 stomp 1.1 부터 기능 추가됨
frontend에서 웹 소켓 연결 방식
const url = "websocket server url";
const socket = new SockJS(url);
const stompClient = Stomp.over(socket, {protocols: Stomp.VERSIONS.supportedProtocols()};
...
{ protocols: ['v11.stomp', 'v12.stomp'] }
backend에서 웹 소켓 서버 방식
...
@Configuration
@EnableWebSocketMessageBroker
public class webSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry)
{
registry.addEndpoint("/secured/ws-stomp").addInterceptors(talkStompHandshakeInterceptor).setAllowedOrigins("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry)
{
registry.enableSimpleBroker("/chat", "/ready");
registry.setApplicationDestinationPrefixes("/event");
}
...
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry)
{
registry.enableSimpleBroker("/chat", "/ready")
.setHeartbeatValue(new long[] {3000, 3000})
.setTaskScheduler(heartBeatScheduler());
}
@Bean
public ThreadPoolTaskScheduler heartBeatScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(1);
scheduler.setThreadNamePrefix("stomp-heartbeat-thread-");
scheduler.initialize();
return scheduler;
}