[Spring] OpenVidu 미디어 서버 세션 유지하기

박성우·2023년 6월 15일
0

Spring

목록 보기
4/10

OpenVidu 플랫폼을 이용해서 미디어 서버를 구축하고 N:N 화상 스터디를 구현하는 과정에서 문제가 발생하였다.

문제는 스터디룸의 역할을 하는 OpenVidu 서버 내에 생성된 세션이 주기적으로 삭제가 되는 것이였는데, 찾아보니 비활성화 된 세션을 주기적으로 모니터링하며 삭제하는 Garbage Collector가 존재하였다.

결국 Garbage Collector 제어가 필요했는데 .env 파일을 수정해서 제어하는 방법이 존재하였다.

OPENVIDU_SESSIONS_GARBAGE_INTERVAL 값을 0으로 수정하면 Garbage Collector가 비활성화됨과 동시에 OPENVIDU_SESSIONS_GARBAGE_THRESHOLD 속성 또한 무효화가 되기 때문에 Interval 값을 0으로 수정하였다.

해당 방법으로 비활성 세션이 사라지는 문제는 해결이 되었지만 특정 상황에서 여전히 세션이 사라지는 현상이 발생했다.

우리가 구현하고자 하는 방향은 스터디룸에서 모든 인원이 방을 나가도 스터디룸이 남아있어야 하기 때문에, OpenVidu 서버 내의 세션이 사라지지 않고 유지되야 필요가 있었다.

특정 상황에 대한 조건은 다음과 같다.

  • 세션이 생성된 후, 한번이라도 Connection이 발생하지 않았다면 세션은 영구적
  • Connection이 하나 이상 유지되면 세션은 계속 유지됨
  • 한번이라도 Connection이 발생한 후 Connection이 하나도 존재하지 않게될 경우 세션이 삭제됨

해결책을 찾기 위해 구글링을 해본 결과, Connection이 하나도 존재하지 않게될 경우, 즉 스터디룸에서 모든 참가자가 나갈 경우에 세션이 삭제되지 않게 하는 방법은 존재하지 않는다는 것(OpenVidu 개발자 왈..)을 알게되었고 해당 문제를 해결할 방법으로 두 가지를 생각해보았다.

  1. 유저가 이미 삭제된 세션으로 접근할 경우 새로운 세션을 생성해서 해당 세션에 유저를 입장시키는 방법
  2. 모든 세션에 봇을 하나씩 두고 Connection이 계속 유지되게 하는 방법

첫 번째 방법은 사실상 세션이 삭제되는 것을 피할 수는 없지만 유저 입장에서는 세션이 계속 유지되는 것으로 인지될 것이다. 또한, 두 번째 방법은 모든 세션에 하나씩 봇이 존재해야 하기 때문에 리소스 낭비가 심할 것으로 보였기 때문에 첫 번째 방법으로 시도하게 되었고 다음과 같은 과정이 필요하였다.

스터디룸에 유저 입장 -> OpenVidu 서버에 활성화되어 있는 세션 목록 로드 -> 입장하고자 하는 세션 ID가 존재할 경우 해당 세션으로 입장 -> 해당 세션이 없을 경우 입장하고자 했던 세션 ID와 똑같은 ID로 Custom 세션 생성 및 입장

서비스 단에 추가된 코드는 다음과 같다.

@Transactional
public ResponseDto<String> enterRoom(RoomEnterRequestDto requestDto, String sessionId, Member member)
    throws OpenViduJavaClientException, OpenViduHttpException {

    openvidu.fetch();

    List<Session> activeSessionList = openvidu.getActiveSessions();

    Optional<Session> sessionOptional = activeSessionList.stream()
            .filter(s -> s.getSessionId().equals(sessionId))
            .findFirst();

    Session session;
    if (sessionOptional.isPresent()) {
        session = sessionOptional.get();
    } else {
        // 같은 sessionId로 Custom 세션을 새로 생성
        session = openvidu.createSession(new SessionProperties.Builder().customSessionId(sessionId).build());
    }
    ...

유저를 세션으로 연결하기 전에 해당 API가 호출되기만 하면 세션이 존재하지 않을 경우 같은 ID값으로 새로 생긴 세션에 문제없이 입장이 되었다.

아무래도 미디어 서버를 직접 구축하지 않고 플랫폼을 사용하다보니 이러한 커스터마이징에 제한이 존재하는 것으로 보인다.

profile
Backend Developer

0개의 댓글