[Kurento] Kurento SFU 이해하기

Suzie·2023년 1월 25일
0
post-thumbnail
  1. Kurento Media Server를 VM에 올리기 위해 필요한 방화벽

    • 사내 PC에서 VM에 들어가기 위해 port :22 개방
    • VM에서 Docker 다운 위해 .docker.com, .docker.io 개방
    • 쿠버네티스에서 Kurento Media Server 접근 위해 8888/TCP(Socket), 5000-5050(UDP) 개방
    • 웹에서 Kurento Media Server 접근 위해 8888/TCP(Socket), 5000-5050(UDP) 개방
  2. SDP(Session Description Protocol) : WebRTC에서 스트리밍 미디어의 해상도나 형식, 코덱 등의 멀티미디어 컨텐츠의 초기 인수를 설명하기 위해 채택한 프로토콜

    • Offer/Answer 모델(peer가 미디어 스트림 교환할 것이라고 제안하면, 상대방으로부터 응답이 오기를 기다림)
    • 응답을 받으면 피어가 수집한 ICE 후보 중 최적경로 선택
    • peer에서 로컬 데이터 스트림 엔드포인트 생성
  3. ICE(Interactive Connectivity Establishment) : 두 개의 단말이 P2P 연결을 가능하게 하도록 최적의 경로를 찾아주는 프레임워크

ICE가 STUN,TURN 서버를 이용해 상대방과 연결 가능한 Candidate 가짐(IP주소와 프로토콜, 포트의 조합으로 구성된 연결 가능한 네트워크 주소)

  1. Controller
@Override
    public void handleTextMessage(WebSocketSession webSocketSession, TextMessage response) throws Exception {
        final JsonObject jsonMessage = gson.fromJson(response.getPayload(), JsonObject.class);
        switch (jsonMessage.get("type").getAsString()) {
            case "joinRoom":
                JoinRoomRequest joinRoomRequest = mapper.readValue(response.getPayload(), JoinRoomRequest.class);
                signalingService.joinRoom(joinRoomRequest.getUserId(),joinRoomRequest.getChannelId(),webSocketSession);
                break;
            case "sdpOffer":
                SdpOfferRequest sdpOfferRequest = mapper.readValue(response.getPayload(), SdpOfferRequest.class);
                signalingService.sdpOffer(webSocketSession,sdpOfferRequest.getUserId(),sdpOfferRequest.getSdpOffer());
                break;
            case "leaveRoom":
                signalingService.leaveRoom(webSocketSession);
                break;
            case "addIceCandidate":
                AddIceCandidateRequest addIceCandidateRequest = mapper.readValue(response.getPayload(), AddIceCandidateRequest.class);
                signalingService.addIceCandidate(webSocketSession,addIceCandidateRequest.getUserId(),addIceCandidateRequest.getCandidateInfo());
                break;
            default:
                break;
        }
    }

req) joinRoom(myUserId,channelId)

  1. channelId로 room 가져오기 getRoomByChannelId
    • room 없으면 생성하기 createNewRoomByChannelId
  2. 내 outgoingMediaEndpoint 생성하기
    • addIceCandidateFoundListener 붙여서 이벤트 감지될 때마다 IceCandidateResponse 보내기
    • synchronized(webSocketSession)
  3. 나 Participant 등록(userId, room, webSocketSession, outgoingMediaEndpoint)
    • outgoingMediaEndpoint 만들기
  4. 현재 방에 있는 Participant 찾기
    • participants.forEach(새로운 유저 왔음을 알리기)
    • 나에게 현재 있는 유저 정보 내려주기
  5. 유저 insert

req) sdpOffer(myUserId,sdpOfferRequest(userId,sdpOffer))

  1. 내 participant 찾기
    • 없을 경우 에러 -> join 부터 다시 하기
  2. sender의 participant 찾기
    • 없을경우 에러
  3. 너로부터 incoming 가져오기
  4. 나의 incoming에 3 추가
  5. 내 session으로 sdpAnswer 전송
  6. incoming.gatherCandidates();

req) leaveRoom(myUserId)

  1. 내 participant 찾기
    • 없을 경우 에러
  2. participants에서 나 지우기
    • endpoint release
  3. room의 participants 가져와서
    • forEach 나의 incoming 모두 지우기(endpoint release)
    • 만약 비어있다면, 내가 마지막이면 room 지우기(pipeline release)

req)addIceCandidate(myUserId, IceCandidateRequest(userId, CandidateInfo(candidate,sdpMid,sdpMLineIndex)))

  1. 내 participant 찾기
    • 없을 경우 에러 -> join 부터 다시 하기
  2. sender의 participant 찾기
    • 없을경우 에러
  3. incoming 가져와서 addCandidate
    • 만약 1,2가 같으면 outgoing에 addCandidate

0개의 댓글