분류 Nodejs

JavaScript 및 WebRTC를 사용하여 화상 채팅 앱을 구축

컨텐츠 정보

  • 조회 61 (작성일 )

본문

1 부 : WebRTC 이해 


이것은 WebRTC 시리즈의 첫 번째 튜토리얼입니다. 이 시리즈의 목적은 WebRTC가 무엇이며 웹 앱에서 어떻게 사용할 수 있는지 설명하는 것입니다.


이 부분에서는 WebRTC를 사용하여 앱을 개발하는 데 필요한 다양한 개념을 이해합니다.


이 시리즈의 자습서 

  1. WebRTC 이해 (이 튜토리얼)
  2. 코드에서 WebRTC 구현

소개 


Covid-19 대유행 이전에 웹 화상 회의 플랫폼과 앱에 익숙하지 않으셨다면 지금 모두 알고 계시며 그중 하나를 사용 하셨을 것입니다.


현재 진행중인 COVID-19 상황은 이전보다 훨씬 더 많은 사람들이 재택 근무를 하고 있으며 회사는 웹 회의를 직원과 고객 간의 주요 커뮤니케이션 수단으로 사용하고 있습니다.


그리고 전 세계의 많은 사람들이 사회적 거리두기 조치를 시행하면서 봉쇄 상태에 있기 때문에 가족 및 친구와 시간을 보내는 것조차 이제는 온라인 화상 통화로 제한됩니다. 파티에서 비즈니스 회의에 이르기까지 이러한 화상 회의 플랫폼은 이제 거의 모든 사람에게 일반적입니다.


이 튜토리얼 시리즈의 목적은 이러한 화상 회의 웹 애플리케이션을 개발하는 방법을 가르치는 것입니다. 또한,이 시리즈는 실시간 광고, 멀티 플레이어 게임, 라이브 방송, e- 러닝과 같은 애플리케이션을 구축하는 방법을 배우고 자하는 모든 개발자에게 확실히 도움이 될 것입니다.


기초 


이러한 웹 앱 개발을 시작하기 전에 전자 회의 애플리케이션이 간단한 채팅 웹 앱과 어떻게 다른지 이해해야 합니다.


간단한 채팅 웹 앱에서 두 브라우저가 서로 메시지를 보내야 하는 경우 일반적으로 조정과 메시지 전달을 위해 중간에 서버가 필요합니다. 그러나 중간에 서버가 있으면 브라우저 간의 통신이 지연됩니다. 이 지연은 채팅 앱의 유용성에 거의 영향을 주지 않습니다. 이 지연 시간이 (예를 들어) 5 초 이더라도 이 채팅 응용 프로그램을 계속 사용할 수 있습니다.


그러나 화상 회의 애플리케이션의 경우 이 지연이 상당합니다. 그러한 응용 프로그램을 사용하는 사람과 대화하는 것은 매우 어려울 것입니다. 5 초 후에 당신의 목소리를 받는 사람과 이야기를 한다고 상상 해보세요. 얼마나 짜증 나는지 알 수 있습니다.


따라서 화상 회의를 위해서는 브라우저 간의 실시간 통신이 필요합니다. 이러한 통신은 서버 사이에서 서버를 제거하면 가능합니다. 이것이 바로 웹 브라우저와 모바일 애플리케이션에 간단한 API를 통한 실시간 통신을 제공하는 오픈 소스 프레임 워크인 WebRTC를 사용해야 하는 이유입니다.


WebRTC 


WebRTC는 Web Real-Time Communication을 의미합니다. 서버없이 피어-투-피어 통신을 가능하게 하며 연결된 피어간에 오디오, 비디오 및 데이터를 교환 할 수 있습니다. WebRTC를 사용하면 서버의 역할은 두 피어가 서로를 검색하고 직접 연결을 설정하는 데 도움이 되는 것으로 제한됩니다.


Alt Text 


Alt Text 


WebRTC없이 처음부터 애플리케이션 (피어 투 피어 통신이 필요한)을 빌드하려면 다음과 같은 일반적인 문제를 처리하는 풍부한 프레임 워크와 라이브러리가 필요합니다.

  • data loss
  • connection dropping
  • NAT traversal
  • Echo cancellation
  • Bandwidth adaptivity
  • Dynamic jitter buffering
  • Automatic gain control
  • Noise reduction and suppression

WebRTC를 사용하면 이 모든 것이 브라우저에 기본 제공됩니다. WebRTC는 이러한 모든 문제를 자동으로 처리합니다.이 기술에는 플러그인이나 타사 소프트웨어가 필요하지 않습니다. 오픈 소스이며 소스 코드는 http://www.webrtc.org/에서 무료로 사용할 수 있습니다.


대부분의 주요 브라우저 (예 : Chrome, Firefox 등)가 WebRTC 프레임 워크를 구현하고 개발자를 위해 WebRTC의 API를 노출했지만 브라우저 버전이 이를 지원하는지 확인하는 것이 좋습니다. 여기에서 WebRTC를 지원하는 모든 브라우저 목록을 찾을 수 있습니다.


WebRTC APIs 


WebRTC는 실시간 통신을 달성하기 위해 함께 작동하는 여러 상호 관련된 API 및 프로토콜로 구성됩니다. 이 튜토리얼 시리즈에서 사용할 가장 중요한 API는 — 데모를 보려면 링크를 클릭하십시오.

  • getUserMedia(): capture audio and video.
  • MediaRecorder: record audio and video.
  • RTCPeerConnection: stream audio and video between users.
  • RTCDataChannel: stream data between users.

Signaling 


두 동료가 서로 통신을 시작하기 전에 서로에 대한 많은 정보를 알아야 합니다.

  • 통신에 사용할 수 있는 다른 피어가 있는 경우.
  • 외부에서 볼 수 있는 피어의 IP 주소 및 포트와 같은 네트워크 데이터
  • 세션 제어 메시지 — 통신을 열거나 닫는 데 사용
  • 오류 메시지
  • 코덱, 코덱 설정, 대역폭 및 피어가 전송할 미디어 유형과 같은 미디어 메타 데이터
  • 보안 연결을 설정하는 데 사용되는 주요 데이터

위의 정보가 무엇을 의미하는지 이해하지 못하더라도 걱정하지 마십시오. 중요한 것은 직접 연결을 설정하기 전에 많은 정보를 교환해야 한다는 것을 인식하는 것입니다. 이러한 정보를 메타 데이터라고 할 수 있습니다.


시그널링은 초기 통신을 조정하고 피어 (브라우저)간에 메타 데이터를 전송할 수 있는 메커니즘을 의미합니다. 따라서 처음에 피어는 신호 메커니즘을 사용하여 서로 통신합니다. 주로 다른 피어를 발견하고 그들 사이에 직접 연결을 생성하는 데 필요한 정보를 공유합니다. 직접 연결이 설정되면 그 이후에는 시그널링 역할이 없습니다.


Remember  — 신호를 보내려면 서버가 필요합니다.


세션 설명 프로토콜 :-


  • 신호 메커니즘 (방법, 프로토콜 등)은 WebRTC에 의해 지정되지 않습니다. 우리가 직접 구축해야 합니다. (복잡한 작업 인 것 같지만, 그렇지 않습니다.이 시리즈에서는 시그널링에 Socket.IO를 사용할 것이지만 대안이 많이 있습니다.)
  • WebRTC는 제안 및 답변으로 피어간에 위에서 언급 한 미디어 메타 데이터의 교환 만 필요합니다. 제안 및 답변은 ​​다음과 같은 SDP (Session Description Protocol) 형식으로 전달됩니다.


v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0

... 

  • 위의 형식에서 각 줄이 무엇을 의미하는지 궁금하다면 걱정하지 마세요. WebRTC는 노트북 / PC에있는 오디오 / 비디오 장치에 따라 자동으로 생성합니다.

그렇다면 WebRTC 애플리케이션은 어떻게 작동합니까? 


지금까지 WebRTC가 무엇인지, Signaling이 무엇인지, 개발자가 사용할 수 있는 다양한 API가 무엇인지 설명했습니다. 이제 이 모든 것이 어떻게 함께 작동하는지 살펴 보겠습니다. 이것을 알면 코드 작성을 시작할 수 있습니다.


논의하기 전에 IP 주소와 포트가 무엇인지 이해해야 합니다.

  • 인터넷에 연결된 각 장치는 IP 주소를 사용하여 식별됩니다.
  • 포트 번호는 인터넷 또는 기타 네트워크 메시지가 장치에 도착할 때 전달 될 특정 프로세스를 식별합니다. 포트 번호는 인터넷의 데이터가 장치 내의 올바른 위치로 전달되도록 사용됩니다.

따라서 인터넷에 연결된 각 장치에는 IP 주소와 많은 PORT (일반적으로 65,536 개)가 있습니다.


RTCPeerConnection API 및 신호 : 제안, 답변 및 후보


앞서 논의 했듯이 WebRTC의 RTCPeerConnection API는 사용자 간에 오디오와 비디오를 스트리밍 하는 데 사용됩니다. 따라서 Signaling은 RTCPeerConnection과 함께 작동하여 브라우저 간 직접 연결을 설정합니다.


이 프로세스를 초기화하기 위해 RTCPeerConnection에는 두 가지 작업이 있습니다.


  • 해상도 및 코덱 기능과 같은 로컬 미디어 조건 (오디오 및 비디오)을 확인합니다. 제안 및 응답에 사용되는 메타 데이터이며 신호를 통해 전송됩니다.
  • 신호를 통해 전송되어야 하는 앱 호스트의 잠재적 네트워크 주소 (후보라고 함) (IP 주소 및 PORT 번호로 구성됨) 가져 오기


이 로컬 데이터가 확인되면 신호 메커니즘을 통해 원격 피어와 교환해야 합니다.


Amy가 Bernadette에게 전화하려고 한다고 상상해보십시오. 다음은 전체 제안 / 답변 메커니즘에 대한 자세한 내용입니다. 먼저 미디어 조건에 대한 정보를 공유하는 방법에 대해 논의하겠습니다.


  1. Amy는 RTCPeerConnection 개체를 만듭니다.
  2. Amy는 RTCPeerConnection createOffer() 메소드를 사용하여 오퍼 (SDP 세션 설명)를 작성합니다.
  3. Amy는 setLocalDescription()을 호출하여 생성 된 오퍼 (세션 설명)를 생성 될 연결의 로컬 미디어 설명으로 설정합니다.
  4. Amy는 제안을 문자열로 묶고 신호 메커니즘을 사용하여 Bernadette에 보냅니다.
  5. Bernadette는 Amy의 제안과 함께 setRemoteDescription()을 호출하므로 RTCPeerConnection이 Amy의 설정에 대해 알 수 있습니다.
  6. Bernadette는 createAnswer()를 호출하고 이에 대한 성공 콜백 함수는 로컬 세션 설명 (Bernadette의 대답)을 전달합니다.
  7. Bernadette는 setLocalDescription ()을 호출하여 그녀의 대답을 지역 설명으로 설정합니다.
  8. 그런 다음 Bernadette는 신호 메커니즘을 사용하여 Amy에게 엄격한 답변을 보냅니다.
  9. Amy는 setRemoteDescription ()을 사용하여 Bernadette의 대답을 원격 세션 설명으로 설정합니다.

이제 Amy와 Bernadette도 네트워크 정보를 교환해야 합니다. "후보 찾기"라는 표현은 ICE 프레임 워크를 사용하여 네트워크 인터페이스 및 포트 (피어에 존재하고 다른 피어와의 직접 연결 설정에 사용할 수 있음)를 찾는 프로세스를 나타냅니다.


  1. Amy는 onicecandidate 핸들러를 사용하여 RTCPeerConnection 객체를 생성합니다.
  2. 네트워크 후보를 사용할 수 있게 되면 핸들러가 호출됩니다.
  3. 핸들러에서 Amy는 신호 채널을 통해 문자열 화 된 후보 데이터를 Bernadette에 보냅니다.
  4. Bernadette는 Amy로부터 후보 메시지를 받으면 addIceCandidate ()를 호출하여 후보를 원격 피어 설명에 추가합니다.

WebRTC는 ICE Candidate Trickling을 지원합니다.이를 통해 발신자는 초기 제안 후 수신자에게 후보자를 점진적으로 자동으로 제공하고 수신자가 모든 후보자가 도착할 때까지 기다리지 않고 자동으로 통화를 시작하고 연결을 설정할 수 있습니다. ICE Candidate Trickling을 이해하지 못하더라도 걱정하지 마십시오. 중요한 것은 WebRTC가 피어가 오퍼를 생성하면 자동으로 ICE 후보 (IP 주소 포함)를 생성한다는 것입니다. 신호를 통해 이러한 후보를 수신하고 전송하는 데 필요한 방법 만 구현하면 됩니다.


미디어 조건 및 아이스 후보에 관한 정보가 두 피어간에 공유되면 WebRTC는 자동으로 피어간에 직접 연결을 생성합니다.


신호 후 — ICE를 사용하여 NAT 및 방화벽에 대처 


따라서 모든 WebRTC 연결 엔드 포인트가 직접 통신하기 위해 다른 피어와 교환 할 수 있는 고유 한 IP 주소 및 PORT 번호를 가질 것으로 예상하는 것은 당연합니다.


Alt Text 


그러나 그것은 그렇게 간단하지 않습니다. 여기에 문제를 일으킬 수 있는 두 가지 요인이 있습니다. 웹 회의 응용 프로그램을 사용하려면 먼저 이러한 문제를 처리해야 합니다.


Problem 1 — NAT 


컴퓨터 네트워크에 익숙하다면 NAT가 무엇인지 알 것입니다. 모르더라도 걱정하지 마세요. 여기에서 설명하겠습니다.


IP 주소가 무엇인지 이미 알고 있습니다. 인터넷에 연결된 장치를 식별하는 주소입니다. 논리적으로 인터넷에 연결된 각 장치에는 고유 한 IP 주소가 있어야 합니다. 그러나 이것은 전적으로 사실이 아닙니다.


IPv4 주소의 길이는 32 비트이며 이는 약 40 억 개의 고유 주소가 있음을 의미합니다 (2³² = 4,294,967,296). 2018 년 말에 인터넷에 연결된 장치는 약 220 억 개였습니다. 따라서 IP 주소가 40 억 개에 불과하다면 어떻게 220 억 개의 장치를 인터넷에 연결할 수 있을까요? 이에 대한 답은 NAT입니다.


인터넷을 관리하는 사람들은 다음과 같은 해결책을 제시했습니다. 전체 IPv4 주소 범위를 공용 IP 주소와 개인 IP 주소라는 두 그룹으로 나누었습니다. 이제 각 공용 IP 주소는 하나의 장치에만 할당 할 수 있지만 개인 IP 주소에 대해서는 동일하지 않습니다. 자세한 내용은 아래 이미지를 참조하십시오.


Alt Text 

위 그림에서 각 라우터에는 두 개의 IP 주소가 있습니다. 하나는 공용 IP 주소 (서버를 향함)와 하나는 사설 IP 주소 (내부 네트워크를 향함)입니다. 따라서 내부 네트워크 1 내부의 장치가 서버에 요청을 보내면 서버는 동일한 IP 주소 (예 : 180.190.104.50)에서 오는 요청을 보게 됩니다.


따라서 이는 각 라우터가 하나의 공용 IP 주소를 장치의 여러 개인 IP 주소에 매핑 한다는 것을 의미합니다. 이는 또한 각 장치 (노트북, PC, 스마트 폰)가 라우터의 공용 IP 주소가 아닌 개인 IP 주소 만 알고 있음을 의미합니다. (또한 Google — 내 IP 주소에서 검색하면 Google은 귀하의 비공개 IP 주소가 아닌 라우터의 공개 IP 주소를 확인하기 때문에 Google이 라우터 (귀하가 연결된)의 공개 IP 주소를 알려줍니다.)


따라서 각 장치에는 두 개의 IP 주소 (장치에 할당 된 개인 IP 주소)와 장치가 연결된 라우터에 할당 된 공용 IP 주소가 있다고 말할 수 있습니다.


네트워크 ICE 후보 (브라우저에 의해 생성됨)가 장치의 공용 IP 주소가 아닌 개인 IP 주소를 포함하므로 WebRTC에 문제가 발생할 수 있습니다. 따라서 브라우저가 공용 IP 주소를 알 수 있는 방법을 찾아서 공용 IP 주소를 포함하는 후보를 만들 수 있어야 합니다. 솔루션은 STUN (Session Traversal Utilities for NAT) 서버입니다. 장치가 STUN 서버에 요청하면 STUN 서버는 장치가 연결된 라우터의 공용 IP가 포함 된 메시지로 응답합니다. 이러한 방식으로 STUN 서버는 브라우저가 후보를 생성하도록 도와줍니다.


튜토리얼의 뒷부분에서 STUN을 WebRTC와 통합하는 방법을 살펴 보겠습니다.


Problem 2 — Firewall 


실제로 대부분의 장치는 특정 포트 및 프로토콜을 차단하는 바이러스 백신 소프트웨어와 같은 하나 이상의 방화벽 계층 뒤에 있습니다. 방화벽과 NAT는 실제로 가정용 WIFI 라우터와 같은 동일한 장치에서 구현 될 수 있습니다. WebRTC는 여러 비표준 포트를 사용하기 때문에 일부 방화벽은 두 브라우저간에 직접 연결을 허용하지 않습니다.


Alt Text 


따라서 이를 해결하기 위해서는 TURN (Traversal Using Relay NAT) 서버가 필요합니다. TURN 서버는 기본적으로 릴레이 서버 역할을 합니다. 즉, 직접 (피어 투 피어) 연결이 실패 할 경우 두 피어 사이에서 직접 릴레이 트래픽을 처리합니다. 다음 이미지는 다음을 보여줍니다.


Alt Text 



Solution 


이전에 논의 했듯이 WebRTC를 사용하여 피어 투 피어 연결을 만드는 동안 STUN 및 TURN 서버를 사용해야 합니다. TURN 및 STUN을 webrtc와 통합하려면 TURN 및 STUN 서버의 URL을 포함하는 객체를 RTCPeerConnection () 인수로 전달하기 만하면 됩니다. 다음 코드는 다음을 보여줍니다.

//Object containing TURN/STUN URLs.
var pcConfig = {
  'iceServers': [
    {
    'urls': 'stun:stun.l.google.com:19302'
    },
    {
    'urls': 'turn:192.158.29.39:3478?transport=udp',
    'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
    'username': '28224511:1379330808'
    },
    {
    'urls': 'turn:192.158.29.39:3478?transport=tcp',
    'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
    'username': '28224511:1379330808'
    }
  ]
}........
//Passing the above object to RTCPeerConnection
RTCPeerConnection(pcConfig);


위에서 설명한 것처럼 URL만 전달하면 됩니다. WebRTC는 그 밖의 모든 것을 내부적으로 관리합니다.


다음 다이어그램은 WebRTC 호출 중에 이루어진 모든 연결을 보여줍니다.


Alt Text 


Note:- 

  • 대부분의 경우 성공적인 연결은 TURN 서버없이 STUN 서버 만 사용하여 이루어집니다. 몇 번만 성공적인 호출을 위해 TURN 서버가 필요합니다.
  • 무료 TURN / STUN 서버를 제공하는 회사 (XirSys와 같은)가 있습니다.

축하합니다 


이 튜토리얼의 끝까지 완료했습니다. 이제 WebRTC의 작동 방식을 명확하게 이해해야 합니다.


지금까지 우리는 한 사람 (이 예에서는 Amy)이 WebRTC를 사용하여 다른 사람 (이 예에서는 Bernadette)에게 전화를 시도 할 때 발생하는 일련의 이벤트 만 설명했습니다. 이 모든 것을 코드로 구현하는 방법이 궁금하다면 계속 지켜봐 주십시오. 다음 튜토리얼에서 이러한 모든 개념을 구현하는 코드를 작성하고 설명합니다.


Sources 


https://dev.to/nilmadhabmondal/let-s-build-a-video-chat-app-with-javascript-and-webrtc-380b