<h1><center> WebRTC 라이브러리 </center></h1>
###### title: `WebRTC 라이브러리`
###### tags: `💻 TIL`, `외부 라이브러리`, `WebRTC`
###### date: `2023-11-14T10:39:33.284Z`
> [color=#724cd1][name=데릭]
> [WebRTC Library](https://github.com/stasel/WebRTC)
> [WebRTC in Swift - 잘 설명되어 있음](https://medium.com/@ivanfomenko/webrtc-in-swift-in-simple-words-about-the-complex-d9bfe37d4126)
> [WebRTC - 위키백과](https://ko.wikipedia.org/wiki/WebRTC)
> [WebRTC - 개념 블로그](https://developer.mozilla.org/ko/docs/Web/API/WebRTC_API)
> [WebRTC - 개념 블로그 2](https://medium.com/@hyun.sang/webrtc-webrtc%EB%9E%80-43df68cbe511)
> [WebRTC - 개념 블로그 3](https://ios-development.tistory.com/944)
> [WebRTC - 개념 블로그 4](https://medium.com/@hyun.sang/webrtc-webrtc%EB%9E%80-43df68cbe511)
> [WebRTC - 개념 외국 블로그 1](https://medium.com/@ivanfomenko/webrtc-in-swift-in-simple-words-about-the-complex-d9bfe37d4126)
> [WebRTC - web.dev](https://web.dev/articles/webrtc-infrastructure?hl=ko)
> [WebRTC - iOS Demo](https://github.com/derrickkim0109/WebRTC-iOS)
## 개요
> WebRTC 라이브러리는 무엇인가? <br>
> WebRTC를 알기 위해서는 사전지식이 필요하다.
> 1. OSI 계층구조 - [네트워크 OSI 계층구조](https://hackmd.io/8mjMglmZTVGw2H9P_W-G8w)
> 2. WebSocket - [WebSocket](https://hackmd.io/oJyunb_nS-qRqsDe73dflQ)
## IP 라우팅
> OSI(Open System Interconnection) 중 3계층에는 라우팅이 있다.
- 라우팅에서는 인터넷에 연결된 기기들이 서로 통신하기 위해 IP 주소를 사용한다. 각 기기는 IP 주소(Private IP)를 가지고 있어서 데이터를 보낼 때 이를 이용하여 경로를 결정하게 된다. 그러나 인터넷에 직접 노출되는 것을 피하기 위해, 일반적으로 공유기라 불리는 장치를 사용한다.
- 예를 들어, 노트북과 휴대폰은 모두 Private IP를 가지고 있는데, 이 IP 주소의 보안을 위해 오픈하지 않고 공유기를 통해서 관리하게 된다.
- **공유기 Public IP, 노트북 Private IP**
**NOTE**
> 라우팅: 전기적 신호의 경로를 결정하는 것 <br>
## WebSocket
> 클라이언트와 서버가 Request / Response를 통해 데이터를 교환하지만, 빠른 방식으로 주고 받기 위해 서버와 클라이언트 사이에 Connection을 두어 하나의 Link를 사용하는 것이다.
## WebRTC
> Web Real-Time Communication은 웹 브라우저 간에 플러그인의 도움 없이 서로 통신할 수 있도록 설계된 API이다. 음성 통화, 영상 통화, P2P 파일 공유 등으로 활용될 수 있다.(feat. 위키백과) <br>
> webrtc.org 웹 사이트에 따르면, 이 프로젝트의 목적은 브라우저, 모바일 플랫폼 및 IoT 장치용으로 풍부한 고품질 RTC Application을 개발하고 공통 프로토콜 세트를 통해 모두 통신할 수 있도록 하는 것이다.
- MediaStream - 카메라와 마이크 등의 데이터 스트림 접근
- RTCPeerConnection - 암호화, 대역폭 관리, 오디오, 비디오의 연결
- RTCDataChannel - 일반적인 데이터의 P2P 통신
위의 3가지 객체를 통해서 데이터 교환이 이루어진다.
**NOTE**
> P2P(Peer to Peer): 동등한 위치의 노드를 가진 기기/컴퓨터 간에 직접 통신하는 방식을 말한다. 중앙 서버가 없이 피어들이 직접 연결되어 데이터를 주고 받는다.
- 분산 구조: P2P 시스템은 중앙 서버 없이 피어 간에 직접 통신하기 때문에 분산된 구조를 가진다. 이는 시스템이 확장 가능하고, 중앙 서버에 대한 의존성이 낮아지는 장점이 있다.
- 자원 공유: 파일이나 컴퓨팅 자원과 같은 리소스를 효율적으로 공유할 수 있다. 파일 공유를 예로 들면 P2P 네트워크에서는 각 피어가 파일을 제공하고 다운로드 할 수 있다.
- 확장성: 새로운 피어가 추가되거나 나가더라도 상대적으로 유연하게 대처할 수 있다. 중앙 서버에 의존하지 않기 때문에 확장성이 뛰어나며, 사용자 수나 리소스 양에 따라 성능이 증가할 수 있다.
- 저렴한 인프라 구축: 중앙 서버를 운영할 필요가 없어지므로, 인프라 구축 비용이 낮아진다.
- 네트워크 안정성: 피어 간 통신으로 중앙 서버의 단일 장애 지점이 없어지고, 네트워크의 안정성이 향상된다.
- 프라이버시: P2P 통신은 피어 간 직접 연결이므로 중앙 서버를 통한 중간자 공격에 노출될 가능성이 줄어든다.

> 시그널링 하는 과정
PeerConnection은 두 명의 유저가 스트림을 주고 받는 것이므로 연결을 요청하는 Caller와 연결을 받는 Callee가 있다. Caller와 Callee가 통신을 하기 위해서는 중간 역할을 해 주는 서버가 필요하고 서버를 통해서 SessionDescription을 서로 주고 받아야 한다.
**근데 WebRTC는 서버없이 웹 브라우저 간의 통신인데 왜 서버가 필요해?**
초기 연결 설정 및 중계를 위해서는 서버가 필요하다. WebRTC는 통신을 위한 세션 설정 및 데이터 교환을 돕기 위해 Signaling 서버를 사용한다. 이 서버는 피어 간에 메타데이터를 교환하고 네트워크 환경에서 통신을 설정하는 역할이다. 연결을 설정한 이후에는 P2P 통신이 직접 이루어지면, 데이터는 서버를 경유하지 않고 피어 간에 직접 교환된다.
**NOTE**
> 시그널링(Signaling): RTCPeerConnection들이 적절하게 데이터를 교환할 수 있게 처리해 주는 과정
**P2P 통신과정**
1. 연결 설정(Signaling): Caller와 Callee 간에 상호 작용하여 연결을 설정하기 위해 서버가 사용된다. 각각의 브라우저는 Signaling 서버를 통해 서로에게 세션 정보를 교환하고 통신에 필요한 설정을 수행한다.
2. ICE(Interactive Connectivity Establishment): 이 단계에서는 피어들이 서로에게 직접적인 통신 경로를 찾는 과정이다. 이를 통해 두 피어는 서로에게 직접적인 연결을 설정할 수 있게 된다.
3. DTLS(Datagram Transport Layer Security): P2P 연결이 수립되면 각 피어 간에 데이터가 안전하게 전송될 수 있도록 보안 연결이 설정된다.
4. SRTP(Secure Real-time Transport Protocol): 오디오 및 비디오 데이터의 실시간 전송을 위한 프로토콜로, 안전한 데이터 전송을 보장한다.
### Stun Server & Turn Server
WebRTC는 P2P에 최적화 되어 있다. 즉, Peer 간에 공인 네트워크 주소(Public IP)를 알아야 데이터 교환을 할 수 있게 된다. 하지만, 실제 개개인의 컴퓨터는 방화벽 등 여러 가지 보호장치들이 있어서 Peer 간에 연결이 쉽지 않다. 그래서 Stun/Turn Server를 사용하여 P2P 통신을 가능하게 만든다.
**Stun(Session Travesal Utilities for NAT)**
> 회신 주소, 즉, 송신자 노드의 주소를 반환하는 데 사용되는 인터넷 상의 외부 서버이다.
- 라우터 뒤의 노드는 NAT(Network Address Translation)를 통과하기 위해 STUN 서버에 접속한다.
- STUN 서버에 도착한 후 STUN 서버에 도착한 패킷에는 소스 주소(라우터 주소 == 필요한 노드의 외부 주소)가 포함된다.
- 이 STUN 주소는 서버에 의해 할당되어 다시 전송된다. 이 때, 노드는 외부 IP 주소와 외부 네트워크에서 접근할 수 있는 포트를 받는다.
- 이 주소는 WebRTC에서 추가적인 ICE를 생성하는데 사용된다.
- ICE에는 라우터의 외부 주소와 포트가 포함된다.
- 그 후, 지정된 포트를 통해 전송된 패킷이 우리의 노드로 전달되도록 허용하는 항목이 라우터의 NAT 레지스터에 있다.
**요약**
1. STUN 서버 - 외부 주소 및 접근 포트를 위한 노드를 선택하고 알리기 위한 외부 서비스이다.
2. STUN 서버를 사용하면 라우터의 NAT 레지스터에 항목이 생성되어 필요한 노드로 패킷을 전달한다.
**TURN Server**
STUN 서버의 고급 버전이다. TURN 서버는 STUN 서버의 아날로그(?)역할을 하며 STUN을 대체할 수 있다.
**차이**
예를 들어, 리피터 모드에서 작업할 수 있다. 3/4/5G 네트워크의 노드 간 통신 등으로 노드 간에 P2P 통신이 불가능한 경우에 유용하다. 이 경우에 TURN 서버는 릴레이 모드로 전환되어 노드 간의 중개자 역할을 한다. 물론 이러한 상황에서는 노드가 통신 중개자를 사용하기 때문에 진정한 P2P 연결이라고 할 수는 없다. 그러나 ICE의 내부 메커니즘 내에서만 해당하며, ICE의 노드 외부에서는 직접 통신한다.
**요약**
1. TURN 서버는 노드 간의 P2P 연결 사용에 문제가 있을 경우를 위한 STUN 서버의 확장 버전이다.
2. TURN 서버에는 P2P 연결 문제를 해결하기 위한 릴레이 모드가 있다.
3. 서비스가 3/4/5G 네트워크에서 사용된다면 TURN 서버를 사용하는 것이 좋다.
**-> STUN서버는 TURN과 달리 셀룰러 네트워크에서 사용하기에 적합하지 않다.**
**-> TURN 서버는 대칭형 NAT의 경우에 사용하기에 적합하지 않다.**