Chef.Yeon
Code Cook
Chef.Yeon
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 게임 개발 (1)
      • Unity (1)
    • Android (27)
      • Kotlin (19)
      • 우아한테크코스 5기 (4)
    • Language (11)
      • 파이썬 (3)
      • Java (7)
    • DB (2)
      • SQL (16)
    • Spring (25)
    • 코딩테스트 (56)
    • Git (1)
    • TIL (85)
    • DevOps (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 에라토스테네스의 체
  • 백준
  • 다이나믹 프로그래밍
  • 코틀린 인 액션
  • 우아한테크코스
  • 안드로이드
  • grafana
  • 문자열
  • til
  • Wil
  • elasticsearch
  • 프로그래머스
  • SQL
  • rsocket
  • 프리코스
  • 코틀린
  • Docker
  • 내림차순
  • Android
  • webflux
  • MariaDB
  • kibana
  • 파이썬
  • 코딩테스트
  • java
  • enum
  • 레포지토리
  • ec2
  • spring
  • kotlin

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Chef.Yeon

Code Cook

[TIL - 20230612] OBS 방송 시작 관련 문제 해결
TIL

[TIL - 20230612] OBS 방송 시작 관련 문제 해결

2023. 6. 13. 02:06

 

💻문제점1

잘못된 streamkey를 입력해도 유효하다고 log가 찍힌다. 

@NoArgsConstructor
@Getter
@Setter
@Slf4j
public abstract class RtmpServer implements CommandLineRunner {

    //생략

    @Override
    public void run(String... args) {
        DisposableServer server = TcpServer.create()
//                .host("0.0.0.0")
                .port(1935)
                .doOnBound(disposableServer ->
                        log.info("RTMP 서버가 포트 {} 에서 시작됩니다.", disposableServer.port()))
                .doOnConnection(connection -> connection
                        .addHandlerLast(getInboundConnectionLogger())
                        .addHandlerLast(getHandshakeHandler())
                        .addHandlerLast(getChunkDecoder())
                        .addHandlerLast(getChunkEncoder())
                        .addHandlerLast(getRtmpMessageHandler()))
                .option(ChannelOption.SO_BACKLOG, 128) // 클라이언트가 새로운 연결을 요청할 때 대기하는 큐 크기를 128로 설정
                .childOption(ChannelOption.SO_KEEPALIVE, true) // 특정 시간동안 클라이언트의 요청이 없어도 서버-클라이언트 연결이 끊기지 않도록 설정
                .handle((in, out) -> in
                        .receiveObject()
                        .cast(Stream.class)
                        .flatMap(stream ->
                        {
                                webClient
                                .post()
                                .uri(authAddress + "/broadcasts/{}/check", stream.getStreamName())
                                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                                .body(Mono.just(new User(stream.getStreamKey())), User.class)
                                .retrieve()
                                .bodyToMono(Boolean.class).log()
                                .retryWhen(Retry.fixedDelay(3, Duration.ofMillis(500)))
                                .doOnError(error -> log.info(error.getMessage()))
                                .onErrorReturn(Boolean.TRUE)
                                .flatMap(ans -> {
                                    log.info("스트리머 {} 의 stream key가 유효합니다.", stream.getStreamName());
                                    if (ans) {
                            //생략
                        .then())
                .bindNow();
        server.onDispose().block();
    }
}

 


OBS에서 testNickname이라는 닉네임을 가지는 사용자의 streamKey를 설정하고

 

방송을 시작하면 다음과 같이 연결할 수 없다고 떴다.

 

콘솔 창에는 다음과 같은 오류가 떴다.


🔍문제점1 해결

오류에서 POST요청을 한 경로를 보면 이상한 것을 확인할 수 있다. %7B 어쩌구로 깨진 곳에는 OBS에서 설정한 사용자 닉네임, testNickname이 들어가야 한다.

 

요청 uri가 깨져서 제대로 요청이 안 가는 것일 수도 있겠다는 생각이 들어 이 문제 부터 수정했다.

 

요청 부분을 다음과 같이 수정했다.

.uri(authAddress + "/broadcasts/" + stream.getStreamName() + "/check")

 

그랬더니 깨지지 않고 올바른 경로로 요청이 수행된 것을 확인할 수 있었다.

 

하지만 여전히 연결은 안된다..

 

그리고 깨달았다..! 이 요청은 POST 요청이고 현재 그 요청을 받는 API는 GET 이다...

그래서 GetMapping이 아니라 PostMapping으로 변경해주었다.

    @PostMapping("/{streamer}/check")
    public Mono<Boolean> checkStreamer(@PathVariable("streamer") String streamer, @RequestBody StreamerCheckRequestDto streamerCheckRequestDto) {
        log.info("channelController: " + streamer);
        return channelService.checkBroadcast(streamer, streamerCheckRequestDto);
    }

 

방송 시작을 해보니 무사히 시작되었다.

 

TranscofingService에서도 정상적으로 testNickname 유저 방송에 대해 파일을 생성하는 것을 확인할 수 있었다.


💻문제점2

방송이 시작되면, DB에서 해당 유저의 방송 상태가 true로 변경되어야 한다. 하지만 변경되지 않았다. 

ChannelController에서 로그를 찍어보니 해당 요청인 startBroadcast 메서드에 잘 진입하는 것을 확인할 수 있었다.

 

Postman으로 확인해보니 true라는 결과는 출력하지만 DB에 변경사항이 적용이 안됐다.

    public Mono<Boolean> startBroadcast(String streamer) {
        return channelRepository
                .findByStreamer(streamer)
                .switchIfEmpty(Mono.error(new RuntimeException("존재하지 않는 채널입니다.")))
                .map(channel -> {
                    return channelRepository.save(channel.channelOn());
                })
                .flatMap(channel -> {
                    return Mono.just(true);
                });
    }

 

코드가 수정되고 아직 해당 부분에 테스트 케이스를 안 짰더니 ㅠㅠ


🔍문제점2 해결

다음과 같이 코드를 변경했다.

    public Mono<Boolean> startBroadcast(String streamer) {
        return channelRepository
                .findByStreamer(streamer)
                .switchIfEmpty(Mono.error(new RuntimeException("존재하지 않는 채널입니다.")))
                .flatMap(channel -> {
                    return channelRepository.save(channel.channelOn())
                            .thenReturn(true);
                });
    }

 

이전 코드에서는 save 메서드를 호출하지만, 그에 대한 결과를 처리하지 않았다. 

리액티브 프로그래밍은 호출 시점과 실제 작업 수행 시점을 구분하기 때문에 단순히 호출만 하여서 DB에 반영되지 않은 것이다. save를 호출한 후 해당 Mono 객체에 대한 처리를 thenReturn(true)를 통해 해주었다.

 

방송을 시작하니 DB에 해당 채널의 on_air가 true로 변경되었다.

728x90

'TIL' 카테고리의 다른 글

[TIL - 20230615] EC2 + Docker Compose 통한 배포  (0) 2023.06.16
[TIL - 20230614] docker compose  (0) 2023.06.15
[TIL - 20230608] Webflux + Websocket + Kafka  (0) 2023.06.08
[TIL - 20230606] Webflux + Websocket 전체 채팅  (0) 2023.06.07
[TIL - 20230605] RSocketRequester Redis 저장 실패  (0) 2023.06.05
    'TIL' 카테고리의 다른 글
    • [TIL - 20230615] EC2 + Docker Compose 통한 배포
    • [TIL - 20230614] docker compose
    • [TIL - 20230608] Webflux + Websocket + Kafka
    • [TIL - 20230606] Webflux + Websocket 전체 채팅
    Chef.Yeon
    Chef.Yeon
    보기 좋고 깔끔한 코드를 요리하기 위해 노력하고 있습니다.

    티스토리툴바