[2025.02.24] RTMP & HLS 라이브 송출 구현 중 WebSocket 이슈(로컬)

아스라이지새는달·2025년 3월 15일
0
post-thumbnail

🤦🏻‍♂️ 증상

송출 시작을 했을 때 WebSocket이 열리자 마자 닫히는 문제가 발생하였다.
StandardWebSocketSession closed with CloseStatus[code=1009, ...]

Image

로그를 확인해보니 buffer size가 메시지 크기에 비해 작아서 WebSocket이 닫힌 것을 알 수 있었다.

StandardWebSocketSession[id=fc9cfd5e-0e48-32c7-107e-39289a5b50cb, uri=ws://localhost:8080/stream] closed with CloseStatus[code=1009, reason=No async message support and buffer too small. Buffer size: [8,192], Message size: [45,775]]

🤔 원인

로그에 적힌대로 WebSocket의 버퍼 사이즈가 메시지 사이즈에 비해 작아서 생긴 오류이다.

WebSocket의 기본 버퍼 사이즈는 8KB(8,192 bytes)이므로 영상을 전송하기에는 턱없이 부족한 크기이다.


❗️ 해결법

버퍼 사이즈를 증가시키면 된다.

Spring Boot에서 WebSocket의 동작을 조정하는 설정 클래스인 ServletServerContainerFactoryBean을 이용한다.
기본적으로 WebSocket의 버퍼 크기, 세션 타임아웃 등의 설정을 변경할 때 사용한다.

  • 변경 전 코드
import com.ssginc.showpinglive.handler.VideoStreamHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class RTMPWebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new VideoStreamHandler(), "/stream")
                .setAllowedOrigins("*");
    }

}
  • 변경 후 코드
import com.ssginc.showpinglive.handler.VideoStreamHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;

@Configuration
@EnableWebSocket
public class RTMPWebSocketConfig implements WebSocketConfigurer {

    @Bean
    public VideoStreamHandler videoStreamHandler() {
        return new VideoStreamHandler();
    }

    @Bean
    public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxBinaryMessageBufferSize(128 * 1024);    // 128KB

        return container;
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(videoStreamHandler(), "/stream")
                .setAllowedOrigins("*");
    }

}
  • 주요 변경점
@Bean
public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxBinaryMessageBufferSize(128 * 1024);    // 128KB

    return container;
}

ServletServerContainerFactoryBean 객체를 만들고 setMaxBinaryMessageBufferSize 메서드를 통해 버퍼 크기를 설정한다.
byte 단위이므로 128 * 1024 즉 128KB로 설정하였다.

영상 스트리밍을 하려면 10MB로 설정하는 것이 좋다고 하지만 로그에 약 45KB(45,775 bytes)로 찍혀있어 128KB로도 충분하다고 판단해 우선 128KB로 설정하였다.

Image

버퍼 크기를 늘려준 후 다시 실행해보면 송출 시작을 누른 후 송출 종료를 누르기 전까지 WebSocket이 열린 상태를 유지하는 것을 확인할 수 있다.

profile
웹 백엔드 개발자가 되는 그날까지

0개의 댓글