msdou45 2023. 1. 18. 14:51

____________________________________________________________________________________________________

 

 

Web Rtc 파트

 

=> socket.io 파트에서 설계했던 프로젝트를 하나 더 복사하고, 일부분을 지운 뒤 셋팅.

 

 

폴더 : kimminsoo -> NomadCoders -> zoom_web_rtc

 

 

 

 

1.

비디오 스트리밍과 실시간 대화 등을 하기 전에, 우선 유저로부터 비디오를 가져와야 해. 즉 사전 셋팅이 필요하다.

가장 먼저 유저로부터 비디오를 가져와서 화면에 비디오를 보여줘야 해.

두 번째로, 마이크를 음소거 및 음소거 해제하는 버튼과 카메라를 껐다 켰다 하는 버튼 등을 만들어야 해.

또한 휴대폰에서 만약 이 앱을 사용한다면? 전면 카메라와 후면 카메라를 서로 전환할 수 있는 기능이 있으면 좋겠지.

 

 

2.

Web - rtc.

=> web Real-time communication.

실시간 커뮤니테이션을 가능하게 해주는 기술. 이 기술은 peer-to-peer 이야.

뭔 소리냐.

 

우리가 chat 을 socket 으로 만들었을 때, 그건 peer to peer 이 아니었어.

왜냐? 그 때는 한 서버에 많은 web socket 들이 모두 연결되어 있었어.

그리고 한 web socket 이 메세지를 보냈을 때 서버로 이를 받았어.

그리고 서버가 그 메세지를 다른 소켓들에게 전달했었지.

 

즉 socket io 를 사용하면서 chat room 안에 들어가 있다면, 거기서 발생하는 메세지는 서버를 거쳐서 각 사용자들에게 전달 되는거야.

언제나 서버를 사용해야만 하는 거지.

이처럼 socket 은 peer to peer 이 아니야. 그냥 우리 모두가 서버로 연결되어 있을 뿐이지.

 

허나 webRTC 가 있다면 peer-to-peer 이 가능해.

즉, 내 영상과 내 오디오와 내 텍스트가 서버로 가지 않아. 직접 유저들 사이에서 통신이 이루어지는 거야.

peer-to-peer 속성은 기본적으로 서버가 필요 없으며, 따라서 실시간(real time) 속도가 매우 빠른 이유.

 

만약 내 모든 영상과 오디오를 서버에 업로드하고, 이를 다시 다른 유저들이 다운로드 해야 한다?

서버 비용이 너무 비싸지는 거야.

반면 webRTC 는 peer to peer 속성 덕에 서버를 거치지 않고 유저 끼리 서로의 컴퓨터에 데이터를 직접 전달해. 정확히는 브라우저에.

유저와 유저의 브라우저가 다이렉트로 연결되는 거지.

 

web RTC 가 그렇다고 서버를 아예 필요로 하지 않는다는 것은 아냐.

단지 영상이나 오디오를 전송하기 위해 서버가 필요하다는 게 아닐 뿐.

기본적으로는 우리가 ‘ signaling ‘ 이란 것을 하기 위해 서버가 필요해.

핵심은 시그널링이 끝나면 peer to peer 연결이 이루어 진다는 것. 멋져 멋져

 

 

 

—— signaling ——

 

예를 들어, 내가 A랑 대화를 하고 싶어.

그럼 A의 브라우저가 어디에 있는지를 어케 아는데?

내가 A 와 브라우저 상에서 peer to peer 연결을 만들고 싶다면, 우선 A의 브라우저 정보를 알아야겠지.

예를 들면, A의 ip 주소라던가.

 

즉 대화하고 싶은 상대가 있다면, 상대가 인터넷 어디에 있는지 그 위치와 정보부터 특정해야 한다는 거야.

 

우리가 해야할 것은, 우리의 브라우저로 햐여금 상대가 어디에 있는지를 서버가 알게 해야 한다는 것.

그래서 내 구글 브라우저가 서버한테 말하는 거야. 

“ 이봐, 나는 여기에 있어. 내 ip, 내 오픈 port, 내 서버 구성은 이러해 “

즉 브라우저는 서버에게 ‘ configuration ‘ 를 전달해. 브라우저의 위치와 함께.

나와 A 모두가 서버에게 브라우저의 위치 정보를 전달하는 거지.

그럼 서버가 우리에게 알려주는 거야. “김민수는 여기에 있고, A는 여기에 있어” 라면서 중개해주는 거지.

그럼 나와 A는 서로의 위치를 알 수 있고, 이제부터는 다이렉트로 peer to peer 연결이 시작되는 거지.

 

핵심은, 서버는 비디오와 오디오 정보를 처리하지 않는다는 거야.

단지 다른 사람들이 어디 있는지를 알려줄 뿐.

 

브라우저는 서버에게 인터넷에서의 사용자들의 위치와 settings, configuration, 방화벽이나 라우터가 있는지 등등의 정보를

전달해 줄거야.

서버는 그 정보를 다른 브라우저에게 전달하고, 사용자들의 브라우저는 서로의 위치를 알 수 있게 되는거야.

 

정리하자면,

우리는 peer to peer 로 다른 유저와 연결을 하고 싶은데, 서버를 사용해야 다른 브라우저들의 위치를 알 수 있다는 것.

서로의 위치를 알 수 있게 된다면, 그때부터는 실시간으로 직접 대화가 가능해 지는 것. 이 때 우리의 영상과 오디오가 전달되는 거야.

 

 

 

 

3.

Room 기능을 만들어서 적용시켜 보자.

 

——

// app.js

 

// 방 이름을 입력하고 submit을 할 때. socket 으로 보내서 방을 create / join 한다.

const handleWelcomeSubmit = (event) => {

    event.preventDefault();

    const input = welcomeForm.querySelector("input");

    socket.emit("join_room", input.value, startMedia);

    roomName = input.value;

    input.value = '';

} 

 

// socket Code

socket.on("welcome", () => {

    console.log("someone join!")

})

 

 

____

 

 

// server.js

 

io.on("connection", (socket) => {

    socket.on("join_room", (roomName, done) => {

        socket.join(roomName);

        done();

        socket.to(roomName).emit("welcome");

    })

})

——

 

=> 위 처럼 유저가 방에 입장해서 join 을 한다?

이제부터 web RTC 연결을 시작해야 하는 거야.

 

1) getUserMedia()  즉 유저의 미디어 정보를 가져온다.

2) 유저의 브라우저 간의 RTC 연결을 만들기. 커넥션을 만들어 줘야 해.

——

// app.js

const makeConnection = () => {

    myPeerConnection = new RTCPeerConnection();

// RTC 연결을 하기 위해 유저의 myPeerConnection을 브라우저에 만드는 거야.

}

____

 

3) addStream() 사용. 헌데 해당 함수는 오래된 함수야. 새로운 걸 시용할거야. 허나 핵심은 같아.

우리가 이 단계에서 하고픈 것은 우리 카메라에서 오는 stream 데이터를 가져와서 연결을 만드는 것.

그래야지 우리의 영상과 오디오를 연결을 통해서 다른 브라우저들에게 전달할 수 있을테니.

즉, peer-to-peer 연결 안에다가 영상과 오디오를 집어 넣어야 해.

 

——

// app.js

 

const makeConnection = () => {

    myPeerConnection = new RTCPeerConnection(); 

            // RTC 연결을 하기 위해 유저의 myPeerConnection을 브라우저에 만드는 거야.

    // console.log(myStream.getTracks());

            // myStream 변수에는 getMedia() 함수를 통해서 camera, audio device가 들어가 있는 상황.

            // myStream 에 들어가 있는 camera, audio 트랙을 myPeerConnection 에 집어 넣을거야.

    myStream.forEach((track) => {

        myPeerConnection.addTrack(track, myStream);

            // 브라우저의 카메라와 마이크의 데이터 stream 을 가져와서 그것을 peer 연결 안에 집어 넣었어.

    })

}

——

 

4) 이제 각 브라우저들은 저마다 자신들의 stream 을 peer Connection 에 집어 넣을거야.

다음으로, 우리는 브라우저들 끼리 연결해 줘야 해.

 

——

// app.js

 

// socket Code

socket.on("welcome", () => {

    console.log("someone join!")

})

——

=> 만약 누군가가 room 에 들어갈 경우, 기존에 room 에 있던 유저들은 새롭게 누군가가 방에 들어왔다며 알림을 받아.

즉, 이미 room 에 있던 유저가 주체가 되어서 offer 라는 걸 만들거야.

offer 는 뭐 괴상한 텍스트로 이루어져 있는데, 대충 말하자면 ‘ 다른 브라우저가 참가할 수 있도록 초대장을 만든 것’ 이라고 할 수 있어.

 

offer 를 만듦으로서 유저는 다른 브라우저들과 연결될 준비를 끝마친 거야.

 

 

5) 이번 단계는 setLocalDescription 이라는 걸 만드는 것.

4번 단계에서 우린 offer 를 만들었어. 이제 이 offer 로 연결을 구성해야 해.

 

——

// socket Code

socket.on("welcome", async () => {

    // 자신이 이미 들어와 있는 방에 다른 누군가가 들어왔을 경우, 이미 들어와 있던 유저가 주체가 되어 offer 를 생성한다.

    // offer 는 다른 브라우저들이 rtc 연결에 참가할 수 있도록 '초대장' 을 만든 것이라 생각하면 돼.

    // offer 는 실시간으로 만들어지는 RTC 의 세션.

    // 우리가 누구이며, 어디에 있고, 그런 정보들이 들어가 있다고 보면 됨.

    const offer = await myPeerConnection.createOffer();

    

    myPeerConnection.setLocalDescription(offer)

})

——

=> 초대장을 peer 연결에 넣었어. 마치 아까 미디어 track 을 peer 에 집어 넣었던 것 처럼.

 

다음으로, offer 를 room 에 새로 들어온 유저에게 전달해야 해.

 

____

// app.js

 

 

// socket Code

socket.on("welcome", async () => {

    // 자신이 이미 들어와 있는 방에 다른 누군가가 들어왔을 경우, 이미 들어와 있던 유저가 주체가 되어 offer 를 생성한다.

    // offer 는 다른 브라우저들이 rtc 연결에 참가할 수 있도록 '초대장' 을 만든 것이라 생각하면 돼.

    // offer 는 실시간으로 만들어지는 RTC 의 세션.

    // 우리가 누구이며, 어디에 있고, 그런 정보들이 들어가 있다고 보면 됨.

    const offer = await myPeerConnection.createOffer();

    

    // track 을 peer 연결에 넣었던 것 처럼 offer = 나에 대한 정보 = 초대장을 peer 연결에 넣어.

    myPeerConnection.setLocalDescription(offer)

    // 서버에서 해당 room 에 들어가 있는, 정확히는 기존에 room 에 있던 유저가 새로 room 에 들어온 유저에게 offer 를 줄거야. 

    socket.emit("offer", offer, roomName);

})

 

/*

기본적으로 기존에 방에 있던 유저(혹은 유저들)이/가, 새로운 유저가 room 에 들어오면

서버의 socket.to(roomName).emit("welcome") 알람을 받아서 자신들의 offer 를 

새로 room에 들어온 유저에게 넘겨주는 방식.

즉 아래의 socket.on 이벤트는 새롭게 room 에 들어온 브라우저가 실행하게 될 이벤트.

*/ 

socket.on("offer", async (offer) => {

 

})

——

 

=> 이게 바로 시그널링 프로세스.

 

 

 

6) 자, 기존의 room 에 있던 인원이 offer 를 던졌고, 새로 room에 들어온 유저가 offer 를 받았어.

이제 새로 room 에 들어온 인원은 setRemoteDescription 을 만들어야 해.

——

// app.js

 

socket.on("offer", async (offer) => {

    // 새롭게 room 에 들어온 유저는 기존의 room 에 있던 인원들에게 offer 를 받았어. 이제 이걸 자신의 peer 에 셋팅.

    myPeerConnection.setRemoteDescription(offer);

})

——

 

 

 

 

7) 다음으로, offer 를 받는 유저는 answer 를 생성해야 해.

기존에 room에 있던 유저가 offer 를 생성하고, offer 를 받은 유저(=새로 room에 진입한 유저)가 answer 를 생성한다.

즉 offer 를 받았으니, 이번엔 answer 로 응답하는거야. Answer 를 생성해서 offer 를 보내준 유저들에게 응답해 줘야 해.

 

——

// app.js

 

socket.on("offer", async (offer) => {

    // 새롭게 room 에 들어온 유저는 기존의 room 에 있던 인원들에게 offer 를 받았어. 이제 이걸 자신의 peer 에 셋팅.

    myPeerConnection.setRemoteDescription(offer);

 

    // offer 를 받은 유저는 answer 를 생성한다. 생성해서 어떻게 하는데?

    // 기존의 room에 있던 유저들이 offer 를 보낸 것 처럼, offer 를 받은 신규 유저가 이번엔 answer 를 회답할거야.

    const answer = await myPeerConnection.createAnswer();

    myPeerConnection.setLocalDescription(answer);

    socket.emit("answer", answer, roomName);

})

 

 

// server.js

socket.on("answer", (answer, roomName) => {

        socket.to(roomName).emit("answer", answer);

    })

——

 

 

 

 

그러면, 기존의 room 에 있던 유저들은 “answer” 이벤트로 socket.on 응답을 받아야겠지?

 

——

// app.js

 

socket.on("answer", (answer) => {

    myPeerConnection.setRemoteDescription(answer)

    /*

    myPeerConnection.setLocalDescription() 에는 자신이 만든 것을 넣어두고,

    myPeerConnection.setRemoteDescription() 에는 자신이 받은 것을 넣어둔다.

    이로서 서로가 통신할 수 있게 되는 것.

    */

})

____

 

 

 

 

 

 

8) 자아… 이제 room 안에 속한 유저들은 모두 서로가 서로의 offer과 answer 를 가지게 되었어.

그러면 peer-to-peer 연결의 양쪽에서 icecandidate 라는 이벤트를 실행하기 시작할 거야.

 

ice는 “ Internet Connectivity Establishment “ 라고 해서 “ 인터넷 연결 생성 “ 을 뜻하는 단어.

icecandidate 는 webRTC 에 필요한 프로토콜들을 의미하는데, “ 멀리 떨어진 장치와 소통할 수 있게 하기 위함” 이라고 공식문서에.

즉, icecandidate 는 연결된 브라우저들이 서로 소통할 수 있게 해주는 구체적인 방법.

일종의 중재하는 프로세스 같은 거지.

어떤 소통 방법이 가장 좋은 것인지에 대해 icecandidate 를 쓰는게 어때? 라고 제안하고 있는거야.

즉, webRTC 전용 프로토콜은 아니라는 것. 단지 webRTC 가 구체적인 통신 방법으로서 이를 채용한 것.

 

icecandidate는,

다수의 candidate(후보)들이 각각의 연결에서 제안되고, 그리고 그들은 서로의 동의 하에 하나를 선택해.

그리고 그것을 소통 방식으로 사용한다.

물론 이는 answer 와 다른 모든 것들을 얻고 난 뒤에 일어나야 해.

 

어쨌든, 뭘 해야 하나.

우선 icecandidate event 를 listen 해야 해.

내가 myPeerConnection 을 만들면, 그 즉시 event 를 listen 할거야.

 

icecandidate 는 브라우저들이 소통을 할 때마다 발생하는 이벤트.

그리고 이벤트 때마다 candidate 들이 생성되는데, 이들은 다시 다른 브라우저로 보내줘야 해.

왜? candidate 들은 브라우저들에 의해 만들어지니까.

candidate 는 “ 헤이, 이게 우리가 소통하는 방법이야 “ 라고 브라우저들이 알려주는 ‘방식’ 이거든.

허나 이 candidate 들은 다른 브라우저로 전송되지 않아. 그냥 해당 브라우저가 다른 브라우저와 소통할 때마다 발생하는 거지.

 

 

——

// app.js

 

const makeConnection = () => {

    myPeerConnection = new RTCPeerConnection(); 

           

    myPeerConnection.addEventListener("icecandidate", handleIce);

    myStream.getTracks().forEach((track) => {

        myPeerConnection.addTrack(track, myStream);

    })

}

 

const handleIce = (data) => {

    socket.emit("ice", data.candidate, roomName);

}

 

 

// server.js

 

socket.on("ice", (ice, roomName) => {

        socket.to(roomName).emit("ice", ice);

    })

——

 

 

 

 

 

9) 자아.. 우리가 마지막으로 해야할 것은 addstream event 를 등록하는 것.

 

——

// app.js

 

const makeConnection = () => {

    myPeerConnection = new RTCPeerConnection(); 

    myPeerConnection.addEventListener("icecandidate", handleIce);

    myPeerConnection.addEventListener("addstream", handleAddStream);

    myStream.getTracks().forEach((track) => {

        myPeerConnection.addTrack(track, myStream);

            

    })

}

 

const handleIce = (data) => {

    console.log("got ice candidate")

    console.log(data);

    socket.emit("ice", data.candidate, roomName);

}

 

const handleAddStream = (data) => {

    const peerFace = document.querySelector("#peerFace");

    peerFace.srcObject = data.stream;

}

——

 

 

 

10) 문제가 하나 있어. 현재 서로의 stream 을 공유하고는 있는데,

만약 유저가 자신의 카메라 디바이스 종류를 바꿔버리면 stream 이 맛탱이가 가버리는 버그가 존재해.

 

 

——

// app.js

 

// 카메라 디바이스를 바꾸면 내 화면 뿐 아니라 내 stream 을 공유 중인 다른 유저들의 화면에서도 바뀌어야 해.

const handleCameraChanged = async () => {

    await getMedia(camerasSelect.value);

    if (myPeerConnection) {

        console.log(myPeerConnection.getSenders());

            // getSenders() 에서 현재 내 peer가 보내고 있는 stream에 어떤 track 담겼는지 확인할 수 있어.

        const videoSender = myPeerConnection.getSenders().find((sender) => {

            sender.track.kind === "video";

            // Senders 중에서 track 의 타입이 'video' 인 것을 찾는거야.

        })

        // videoSender 에는 peer 로 보내진 media stream track 에 대한 정보가 담겨있을거야. 이 경우 video 의.

        // Sender 는 track 을 peer 로 보낼 때 그에 대한 정보나 옵션을 컨트롤 할 수 있도록 도와줘.

        // 그리고 Sender에는 replaceTrack 이라는 메서드가 존재하지.

        const videoTrack = myStream.getVideoTracks()[0];

                // 카메라를 change 한 후 내가 사용중인 video track.

                // 위에서 getMedia(camerasSelect.value) 가 이미 바꿔줬었잖아.

        videoSender.replaceTrack(videoTrack);

                // 내가 바꾼 카메라가 stream 에도 그대로 반영되도록.

 

    }

}

____

 

 

 

 

 

10) 한 가지 문제가 더 있어. 우리가 지금 만든 프론트가 스마트폰 에서는 정상적으로 작동하지 않을 거야.

 

먼저 현재 웹사이트를 public 으로 만들어서 폰으로 테스트할 수 있게 해야 해.

——

npm i localtunnel -g

——

local tunnel 은 서버를 전세계와 공유하게 해 준다고. 단, 일시적으로만 무료로.

중요한 건 local tunnel 을 사용하면 서버의 url 을 생성할 수 있게 되는 거.

 

또한, -g 로 설치되어야지 lt  라는 키워드를 사용해서 local tunnel 을 호출할 수 있어.

 

커멘드로 “ lt —port 3000 “ 라고 입력하면 임시로 url 을 발급받을 수 있어.

해당 url 로 폰에서 접속하면 될거야.

 

 

 

11) 문제는, 폰에서는 정상적으로 동작하지 않을 것이란 것. 이는 “ stun service “ 라는 것 때문.

정확히는 뭐가 문제냐면, 내 로컬 컴퓨터랑 폰이 같은 wifi 에 있지 않으면 에러가 발생해.

 

왜?

STUN 서버라는 것이 필요해.

stun 서버는 컴퓨터가 공용 ip 주소를 찾게 도와줘.

같은 wifi 에 속해 있다면 해당 그룹 안에서 폰이 컴퓨터를 찾을 수 있지만, 그렇지 못하다면 폰은 컴퓨터를 찾을 수 없어.

왜냐하면 현재 영상 공유는 peer - to - peer 로 연결을 하고 있기 때문에 서로를 찾아야만 해.

 

stun 서버는 어떤 것을 requet 하면 인터넷에서 내가 누군지를 알려주는 서버.

서버는 나에게 공용 ip 를 알려줄 거야. 

그래야지 내 폰이 내 컴퓨터를 찾게 될 거고.

 

우선, 사용하고자 하는 stun 서버의 리스트를 추가하는 것.

전문적으로 하려면 stun 서버를 직접 만들어야 하지만, 이번 강의에서는 구글이 무료로 제공하는 서버를 사용할 거야.

 

webRTC 를 사용한 실제 서비스나 전문적인 뭔가를 만들고 싶다면, 

아마도 나는 아마 내 고유의 stun 서버를 사용하게 될 것.

 

 

 

11) 복습하자면, stun 서버는 내 장치에 공용주소를 알려주는 서버.

왜냐하면 장치는 공용주소를 알아야 하거든. 그래야 다른 네트워크에 있는 장치들이 서로를 찾을 수 있게 되는거지.

이건 일반적인 url 과는 다른 것 같아.

 

——

myPeerConnection = new RTCPeerConnection({

        iceServers: [

            {

                urls: [

                    "stun:stun.l.google.com:19302",

                    "stun:stun1.l.google.com:19302",

                    "stun:stun2.l.google.com:19302",

                    "stun:stun3.l.google.com:19302",

                    "stun:stun4.l.google.com:19302",

                ]

            }

        ]

    }); 

——

 

 

 

 

12) 추가.

Data Channel 이라는 게 있어.

이건 peer-to-peer 유저가 언제든지 모든 종류의 데이터를 주고받을 수 있는 채널.

줌 클론코딩에서는 비디오와 오디오를 주고 받았는데, Data Channel 을 만들면 

유저들은 이미지, 파일, 텍스트, 게임 업데이트 패킷 같은 것들도 서로 주고 받을 수 있게 되. webRTC 가 한 층 더 진화하는 거지.

 

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createDataChannel

=> 참고. 여기 Example 보면서 코드 짜면 금방 만들 수 있어.

 

 

13)

그럼, webRTC 의 단점은?

단점 이라기 보단, webRTC 를 사용하면 안되는 곳들이 몇몇 있어.

 

일단, 우리가 너무 많은 peer 를 가지게 되면 안좋아.

peer 수가 늘어나면 당연히 webRTC 는 느려질거야.

peer 모두가 모두 서로에게 연결되어 있어. 그래서 완전 스파게티 상태야.

즉 100명의 Peer 가 존재한다면 1명 마다 나머지 99명이랑 peer-to-peer 로 모두 다 라인이 이어져 있다는 뜻이니까.

즉 내가 stream 으로 비디오를 보낸다? 99명에게 다 업로드 해야 해.

아무리 많더라도 5명을 넘기지 않는 선에서만 가동하는 게 좋아.

 

대신, 몇몇 회사는 SFU 라는 걸 사용해. Selective Forwarding Unit 이란 건데, 이건 서버에 의존해.

서버에 연결된 모든 유저가 스트림을 업로드하고 다운로드 하는데, 오로지 서버 하나를 통해서만 행해.

그러니 각각의 유저들은 한 번만 업로드하면 되는 거야. 여전히 다운로드 해야 하는 스트림은 인원수 만큼 이긴 하다만.

허나 다운로드도 RTC 랑 좀 달라.

 

SFU에서 서버는 모든 유저로부터 stream 을 전달 받는데, 서버는 그 스트림들을 압축하고 있어.

그리고 서버는 누가 room 의 호스트인지, 누가 말하고 있는지, 누가 스크린을 공유하고 있는지 등 다 알 수 있어.

즉, 내가 발표하고 있지 않다 = 내가 스트림의 리소스를 사용하고 있지 않다면, 그 때 서버는 나의 stream 을 압축시켜.

그래서 사람들이 스트림을 다운로드할 때 질이 좀 안 좋은 스트림을 다운로드 하겠지.

 

즉, 스크린을 공유하고 있거나 발표하고 있는 사람의 화면이라면, 즉 스트림이 막 활성화 되고 있는 유저라면

서버는 해당 유저의 스트림을 좀 더 좋은 사양으로 유지해서 다른 유저들에게 업로드 해줘.

각각의 유저의 스트림 리소스 상황에 따라서 스트림의 품질을 달리 구별한다는 것.

 

우리가 만약 zoom 을 그대~로 클론 코딩 한다면, 이번 연습에서 사용했던 peer-to-peer 그물망 방식으로는 힘들어.

따라서 우리에겐 SFU 같은 유닛이 필요해.

 

 

그래서 Data Channel 이 좋아.

Data Channel 을 사용한다면 그물망 방식을 사용할지 말지 고민하지 않아도 되거든.

왜냐하면 Data Channel 은 그냥 텍스트야.

그래서 업로드, 다운로드가 매우 빨라.

 

모든 문제는 비디오와 오디오를 다룰 때 발생해. 왜냐하면 개들은 무겁거든.

따라서 zoom 은 매우매우 큰 서버를 가지고 있어야만 해. SFU 도 사용해야 하고.

 

나 같은 개미 개발자가 혼자서 소규모로 개발하기에는, Data Channel 만큼 합리적인 기능이 달리 없다 이거지.

그물망 구조다 하더라도 애당초 다루는 데이터들이 다 텍스트일 테니까.

 

 

 

 

 

14) 간략하게 Data Channel 도입해보기.

 

1. 무언가를 offer 하는 socket이, Data Channel 을 생성하는 주체가 되어야 해.

우리는 offer 만들기 전에 Data Channel 만들어야 .