티스토리 뷰

Swift

Swift - WebRTC란?

DevDiana 2026. 7. 19. 18:11

안녕하세요 Diana 입니다.

 

오늘은 WebRTC에 대해 알아보려고 합니다.

시작할게요~

 


✅ WebRTC(Web RealTime Communication)

WebRTC는 앱이나 브라우저끼리 서버를 거치지 않고 비디오, 오디오, 데이터 등을 실시간 P2P로 주고 받는 방식입니다.

화상통화, 음성통화, 실시간 데이터 전송을 서버 중계 없이 단말끼리 처리하는게 핵심이죠.

 

배경이 되는 네트워크 개념을 훑어보면 아래와 같습니다.

일반 통신 vs 직접 통신

우리가 흔히 쓰는 HTTP는 TCP 기반이라 요청이기 때문에, 응답이 서버를 거치고 패킷 순서와 재전송을 보장하느냐고 지연이 생깁니다.

반면, 음성/영상의 경우 전송에 지연이 없고 빨라야 하기 때문에 WebRTC는 UDP 위에서 작동합니다.

화상통화를 할 때 프레임이 하나 늦게 오느니 버리는 것이 낫다는 것이죠.

 

이렇게 통신이 이루어질 때 우리가 확인해야 하는 것은 통신의 대상이 되는 Peer 들을 어떻게 찾느냐는 것입니다.

대부분의 기기는 공유기(NAT)를 통하기 때문에 공인 IP가 없습니다. 따라서 WebRTC에서는 이 주소를 찾아내기 위해 장치가 붙습니다.

  • NAT(Network Address Translation): NAT은 공유기가 하는 주소 변환입니다. 공유기는 공인 IP를 하나 갖고 거기에 연결된 모든 기기에게 사설 IP 주소를 부여합니다. 하지만 이렇게 주소는 인터넷 상에서는 의미를 가지지 못합니다. A 공유기 아래에서 부여받은 주소는 B 공유기 아래에서는 다른 기기를 나타내기 때문입니다. 이런 이유로 인해 아래에서 알아볼 STUN/TURN이 사용됩니다.
  • STUN(Session Traversal Utililties for NAT): "내 공인 IP 포트가 뭐야?"를 알려주는 서버입니다. 두 기기가 직접 연결하려면 서로의 공인 주소를 알아야하는데 공유기가 매핑을 만들기 전까지 정작 자기 자신의 공인 주소를 스스로 모른다는 딜레마가 발생합니다. 이때 STUN 서버는 거울과 같은 역할을 하며 패킷을 보내면 서버가 "내가 본 너의 주소는 000.0.000.0 이야 라고 알려줍니다. STUN으로 알아낸 주소를 서로 공유하면 대부분은 직접 연결되지만 문제는 Symmetrict NAT처럼 까다로운 공유기가 존재한다는 것 입니다. 이런 NAT은 목적지마다 다른 포트를 열어서 STUN으로 알아낸 주소가 상대방에게는 통하지 않습니다.

  • TURN(Traversal Using Relays around NAT): 일부 공유기는 Symmetric NAT이라는 제한을 사용합니다. 이는 "내가 먼저 연결한 적 있는 상대에게만 나에게 연결할 수 있는 권한"을 부여하는 방식으로 STUN을 통해 주소를 알아내더라도 이 설정이 되어있으면 소용이 없습니다. TURN은 이를 우회합니다. TURN 서버와 연결을 열어두고 모든 데이터를 그 서버를 경유해 중계시킵니다. 상대도 나에게 직접 보내는 대신 서버로 보내고 서버가 나에게 전달하는 방식이죠. 당연히 모든 트래픽이 서버를 거치니 오버헤드(지연, 비용)이 큽니다. 따라서 이 방법은 다른 방법이 전부 실패했을 때만 사용하는 방법입니다.

  • ICE(Interactive Connectivity Estblishment): STUN/TURN을 도구로 사용하여 모은 여러 후보 경로(candidate) 중 실제로 연결되는 최적 경로를 찾아내는 프레임워크입니다. 우선순위는 "직접연결 -> STUN으로 알아낸 공인 주소 경유 -> TURN 중계" 입니다. WebRTC 개발 시 코드의 RTCPeerConnection에 STUN/TURN 서버를 등록하면 실제 후보 수집과 선택은 ICE에서 알아서 합니다.
  • SDP(Session Description Protocol): 여기서부터는 연결이 됐으니 뭘 어떻게 주고받을지를 정하는 부분입니다. SDP는 시그널링에 사용되는 것으로 해상도, 코덱, 포맷, 암호화 방식 같은 미디어에 대한 메타데이터를 기술하는 표준으로 실제 영상/음성 데이터 자체가 아니라 "나는 이런 규격으로 보낼것이다"라는 것을 알려주는 스펙 문서와 비슷합니다. 즉 프로토콜이 아닌 데이터 포맷인 셈이죠. 구조는 UTF-8 텍스트 여러 줄로 되어있고 각 줄이 "타입=값" 형태입니다. 이는 개발자가 직접 작성하는 것이 아닌 라이브러리가 처리하는 방식입니다.

  • 시그널링: 시그널링은 WebRTC에서 유일하게 표준을 정해주지 않는 부분이라 개발자가 설계해야 하는 영역입니다.

WebRTC의 목표는 두 기기가 서버 없이 직접 연결 되는 것입니다. 하지만 여기서 모순이 생기는데 A가 B에게 직접 연결하려면 B의 주소를 알아야하고 B의 주소를 알기 위해서는 B에게 연결되어 직접 물어봐야 합니다. 

따라서 우리는 딱 한번, 처음에만 제 3자의 도움을 빌립니다. 서로 이미 연결할 수 있는 공통의 서버에 둘다 접속해서 그 서버를 통해 자신의 주소를 교환하는 것이죠. 이걸 우린 시그널링이라고 부릅니다.

 

핵심은 이 서버는 연결 성립 전까지만 사용된다는 것입니다. 주소 교환이 끝나면 서버는 빠지며 이후부터는 둘이 직접 통신합니다. 

 

시그널링에서는 우리는 두 가지를 교환합니다.

 

첫째, 상대에게 어떻게 도달하는지에 대한 정보가 담긴 ICE 후보자 입니다.

 

폰은 공유기 뒤에 있기 때문에 사설 IP 만을 가지고 있습니다. 이 주소를 상대에게 알려줘봤자 상대 입장에서는 이는 다른 기기를 가리킬 뿐이죠. 따라서 STUN 서버에 물어봅니다. 그러면 STUN 서버는 외부에서 자신이 어떻게 보이는지 알려줍니다. 문제는 어떤 경로가 실제로 통할지 미리 알 수 없다는 것입니다. 따라서 가능한 주소를 전부 후보로 보내 실제로 뚫리는 것을 골라 씁니다. 후볼르 다 던져놓고 시험해보는 것이죠.

 

두 번째는 상대가 무엇을 알아들을 수 있는지를 나타내는 SDP 입니다.

 

주소를 알아도 서로 말이 통하지 않으면 소용이 없습니다. 내가 H.264로 영상을 인코딩해 보냈는데 상대 기기가 VP8만 디코딩할 줄 알면 화면이 나오지 않죠. 코덱 뿐 아니라 해상도, 오디오 샘플레이트, 암호하 키 등을 우리는 서로 맞춰야 합니다.

 

따라서 시작 전 우리는 조건을 합의하는데 이것이 바로 SDP입니다. 합의 절차는 Offer과 Answer의 두 단계로 이루어집니다. 제안하고 수락하는 것이죠.

Swift 관점에서의 WebRTC

iOS에서는 Google에서 배포하는 WebRTC.framework를 사용합니다. 내부는 C++/Objective-C 코어이고 Swift에서 RTC~ 가 붙은 Objective-C 클래스들을 브릿징 하여 사용합니다.

 

Swift에서 WebRTC를 사용할 때 신경써야 할 점은 두 가지가 있습니다.

 

첫째, 시그널링은 직접 구현해주어야 합니다. 프레임워크가 시그널링은 제공해주지 않으므로 URLSessionWebSocketTask나 Starscream같은 라이브러로 WebSocket 서버를 붙여 SDP, ICE를 JSON으로 주고받습니다.

 

둘째, 배포 방식이 바뀌어 왔습니다. 이전엔 Google이나 CocoaPods로 공식 배포 했지만 지금은 중단되었고 커뮤니티 빌드 를 사용하는경우가 많아졌습니다. 그리고 카메라, 마이크를 사용하므로 NSCameraUsageDescription, NSMicrophoneUsageDescription 권한 문구가 필수 입니다.

 

WebRTC를 사용한 기능으로는 아래와 같은 예시들이 있습니다.


1:1 영상/음성 통화

그룹 화상회의

데이터 채널 활용

원격 지원 / 원격 의료, 교육

저지연 라이브 스트리밍

 

이렇게 오늘은 WebRTC에 대해 알아봤습니다. 개념만 봐서는 복잡하고 아직 이해가 제대로 된 것 같지 않습니다.

따라서 다음 글에는 실제로 위의 개념들을 사용해보고 WebRTC로 간단한 앱을 구현해보도록 하겠습니다.

 

 

출처

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

https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Protocols

https://ios-development.tistory.com/944

https://medium.com/@hyun.sang/webrtc-webrtc%EB%9E%80-43df68cbe511

https://www.youtube.com/watch?v=bWcNEk0H4Y0

https://web.dev/articles/webrtc-infrastructure?hl=ko

'Swift' 카테고리의 다른 글

Swift - WebRTC 구현(2)  (0) 2026.07.22
Swift - WebRTC 구현(1)  (0) 2026.07.20
Swift - API 호출 실패 시 재시도  (0) 2026.07.07
Swift - nonisolated 란  (0) 2026.06.30
Swift - 캐시 지역성(Cache Locality)이란  (0) 2026.06.29
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/08   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함