728x90
What is mediasoup?
- SFU(Selective Forwarding Unit)
- SFU는 오디오, 비디오 스트림을 엔드포인트로 부터 받고 다른 모든 사람들에게 미디어를 전달한다.
- node.js Library
- 서버 없이는 작동될 수 없으며 반드시 node.js 애플리케이션 내에서 임포트되어야한다.
- Signaling agnostic
- 💡 agnostic : '불가지론자, 불가지론의'. 뭐 이런 뜻이라는 데 그냥 '독립적인' 정도로 해석하면 될 것 같다.
- 시그널링 프로토콜이 필요하지 않다.
- 모든 존재하는 WebRTC 엔드포인트에 지원이 가능하다.
SFU
- 하나의 피어는 오직 하나의 스트림만을 보낸다.
- 중앙에 있는 미디어수프 서버로부터 하나 이상의 스트림을 받는다.
MESH
- $n^2$ 형태의 peer-to-peer 로 연결
- 오버헤드 발생 우려
- 미디어 스트림을 처리하는 CPU 사용 처리 뿐만 아니라 대역폭 내에서도 3개 이상의 Peer(사용자)를 사용하지 않는 것이 좋다.
- mediasoup는 기본적으로 소비자(comsumer)와 생산자(producer)에 기반한다.
- 생산자는 미디어 수프 라우터를 통해 미디어를 보내고 소비자도 역시 미디어 수프 라우터를 통해 미디어를 받는다.
- 생산자와 소비자를 생성하기 위해 transport를 생성한다.
- 이러한 transport도 라우터에서 생성된다.
- 라우터는 방을 나타내는 데, 방은 여러 전송을 보낼 수 있으며 각 방에는 생산자 transport 와 소비자 transport가 있다.
- 라우터는 worker로부터 생성되고 worker는 많은 라우터를 가질 수 있다.
- worker는 단일 cpu 코어 내에서 실행되므로 cpu하나당 하나의 worker만 가질 수 있다.
- 만약 4개의 cpu 코어가 있다면 미디어 수프 서버내의 worker 수는 4개로 제한해야한다.
Transport, Producer, Consumer
mediasoup Producer Consumer(1)
⭐️ 구조도 그림에 있는 번호와 아래 번호와 함께 달아둔 설명을 연결해서 봐주세요! ⭐️
- 2 server-side Transport(LP, LC) , 2 client-side Transport(RP, RC)
🔗 용어 정리
- RtpCapabilities : 미디어 수신 관련 정보
- transport : 엔드포인트와 미디어수프 라우터 연결
- getUserMedia : 미디어 스트림 정보를 가져온다.
- connect() :
server-side transport
와 연결을 위한 정보 교환을 수행하는 transport event - produce() : 새로운 Produer에 대한 정보를
server-side Transport
로 전송하는 transport event
- RP(Router Producer)
- LP(Local Producer)
- RC(Router Consumer)
- LC(Local Consumer)
- 각 클라이언트는 라우터의 rtpCapabilities를 서버에 요청을 한다.
- 새로운 디바이스 객체를 생성하고 rtpCapabilities통해 로드 메소드를 호출한다.
- 이때, rtpCapabilities는 나중에 등장하는 deviceRtpCapabilities가 아님을 유의해야한다.
getUserMedia()
메소드를 통해 비디오 트랙 정보를 얻는다.
- 서버에
server-side Transport
를 요청한다.- 요청이 들어오면 라우터는
server-side Transport
를 생성한다.
- 요청이 들어오면 라우터는
- 서버는
server-side Transport
파라미터를 클라이언트로 보낸다. - 클라이언트는 받은 파라미터와 디바이스를 사용해
client-side Send Transport
를 생성한다. client-side Send Transport
가 생성되면client-side Send Transport
의 produce()를 호출한다.- 여기서 produce()는
client-side Send Transport
의 connect 이벤트와 produce 이벤트를 발생시킨다.
- 여기서 produce()는
- (1) connect 이벤트
- return : 서버측으로
dtlsParameters
를 보낸다. - 💡 DTLS Protocol
- return : 서버측으로
- 클라이언트로부터
dtlsParameters
를 받고server-side Transport
에서 connect()를 호출한다.- ✨ Producer 클라이언트 - 서버 연결
- (2) produce 이벤트
- return : 서버측으로 파라미터, 콜백 메소드, 에러 메소드를 보낸다.
- 클라이언트로부터 파라미터들을 받고
server-side Transport
에서 produce()를 호출한다.- produce() 호출시, Producer가 생성된다.
- ✨ Producer 생성
- 서버는 생성된 Producer의
producer id
를 클라이언트로 보낸다. - 👋 이 이후 Consumer 프로세스는 Producer 프로세스와 동일하게 이루어진다.
server-side Transport
와client-side Receive Transport
를 만든다.- (Producer 프로세스의 1~5과정과 동일)
- ↔️
client-side Send Transport
와 차이가 있음 !
- Consumer를 만들기 위해
rtpCapabilities
와producer id
를 서버로 보낸다. - 서버는
rtpCapabilities
와producer id
를 받고 라우터가 미디어 수신이 가능한지 확인한다.- 확인이 완료되면
server-side Transport
에서 consume()을 호출한다. - consume() :
rtpParameters
와consumer id
반환
- 확인이 완료되면
- 이렇게 만들어진
consumer id
와 다른 파라미터들을 클라이언트에 보낸다. - 파라미터들을 클라이언트에 전달한 다음
client-side Receive Transport
의 consume()을 호출한다.- 여기서 consume()은
client-side Receive Transport
의 connect 이벤트를 발생시킨다. - connect 이벤트
- return : 서버측으로
dtlsParameters
를 보낸다.
- return : 서버측으로
- 여기서 consume()은
- 클라이언트로부터
dtlsParameters
를 받고server-side Transport
에서 connect()를 호출한다.- ✨ Consumer 클라이언트 - 서버 연결
mediasoup Producer Consumer(2)
- Producer Peer와 Consumer Peer에서 디바이스 객체를 생성한다. 각각 디바이스를 리턴한다.
- 라우터에서 'rtpCapabilities'를 가져와 클라이언트로 보내고 디바이스 로드 메소드를 호출 하고 'rtpCapabilities'로 해당 디바이스를 정보를 보낸다.
- Producer와 Consumer 각각에 대해 Router Transport를 생성한다.
- Router Transport를 생성하기 위한 옵션을 설정한다.
- Router Transport 두 개가 만들어진다.(Producer, Consumer)
- Router Transport로 부터 여러 파라미터들을 가져와, 클라이언트로 보낸다.
- 해당 파라미터들은 Local Send Transport, Local Receive Transport를 만드는 데에 사용된다. (Local Transport)
- Local Send Transport에서 produce() 메소드를 수행한다.
- 이때 파라미터로 인코딩과 같은 정보를 함께 전달한다.
- produce() 메소드는 producer를 반환한다.
- produce() 메소드에 대한 호출은 connect, produce 이벤트를 발생시킨다.
- connect 이벤트는 dtlsParameters를 반환하고 서버와의 연결을 수행한다.
- produce 이벤트는 'kind', rtpParameters, callback, errback을 반환한다.(errback : 에러가 발생하는 경우를 대비한 메소드)
- 파라미터를 보내고 서버측에서 produce() 메소드를 호출한다.
- 이렇게 되면 서버측에 Producer가 생성되고, Producer는 클라이언트로 producer id를 반환한다.
- 콜백 메소드에 producer id를 전달하여 반환한다.
- Local Transport에게 서버측으로 부터 producer id를 받았다는 걸 알린다.
- Local Producer에게 producer id를 전달한다.
----------- ⬆️ 미디어 송신 -----------
- Consumer Client는 서버로부터 스트리밍 미디어를 소비한다.
- 라우터의 Consumer(rtp capabilities)가 이전 단계에서 받은 producer id로 부터 Producer를 특정하고 producer로 부터 받은 미디어를 수신할 수 있는지 확인한다.이 메소드는 서버사이드 consumer 객체를 리턴하고 이 consumer 객체로 부터 몇몇 파라미터들을 가져올 수 있다.
- 만약 수신이 가능하다면 Router Transport의 consumer 메소드를 호출한다.
- 'rtpCapabilities'를 device로 부터 추출하고 이를 서버로 보낸다.
- 이러한 파라미터 (consumer id, producer id, kind, rtpParameters)를 클라이언트에 보낸다.
- Local Receive Transport로부터 connect 이벤트를 발생시킨다.서버측에서 connect 메소드를 호출하여 Router Transport와 연결을 한다.
- 이 connect 이벤트는 'dtlsParameters'를 반환하고 이를 서버로 보낸다.
- Local Receive Transport에서 consumer 메소드를 실행하고 클라이언트 측 Consumer를 생성한다.
----------- ⬆️ 미디어 수신 -----------
Peer Disconnection
- 시나리오 1 : Producer가 연결을 끊을 때
- 시나리오 2 : Consumer가 연결을 끊을 때
- 시나리오 1
- producer connection issue가 발생했음을 알린다.
- 브라우저가 닫히고 연결 해제를 수행해야한다.
- ⭐️ mediasoup는 자동으로 연결 해제를 수행하지 않는다.
- 웹 소켓을 통해 모든 연결을 모니터링 하는 방법이 있다.
- socket.io를 통해 연결 해제 이벤트를 수신하게 되면 producer Transport의 닫기 메소드를 호출해야한다.
- producer Transport의 닫기 메소드를 호출하면 producer 자기 자신을 종료시킨다.
- 서버 사이드 소비자의 닫기 메소드가 이벤트가 발생한다.
- 서버 사이드 consumer Transport 의 닫기 이벤트를 발생시킨다.
- 이후, 클라이언트의 Transport와 Consumer에게 닫기가 발생했음을 알린다.
- 시나리오 2
- consumer 클라이언트가 연결을 끊을 때 서버 측 disconnect 이벤트가 트리거된다.
- 그런다음 서버 사이드 Transport와 Consumer에서 닫기 메소드를 호출한다.
Reference
- WebRTC: mediasoup (SFU) introduction - Part 1
(https://www.youtube.com/watch?v=DOe7GkQgwPo) - mediasoup :: Documentation
(https://mediasoup.org/documentation)
728x90
'🏠 Framework > Node.js' 카테고리의 다른 글
[WebRTC] WebRTC Overview, NAT, STUN (0) | 2022.08.07 |
---|---|
[Socket.io] WebSocket 동작 원리(직접 구현) (0) | 2021.10.30 |
[Socket.io] WebSocket 개발 환경 세팅 (0) | 2021.10.28 |
[Authentication] OAuth2.0 작동 원리 (feat. Google API) (0) | 2021.09.25 |