WebRTC. 브라우저에서 화상 회의. WebRTC Webrtc 음성 채팅을 사용한 다중 사용자 채팅

전문. P2P 영상채팅 켜짐 WebRTC 기반 Skype 및 기타 통신 수단의 대안입니다. WebRTC 기반의 P2P 영상채팅의 주요 요소는 브라우저와 연락처 서버입니다. P2P 영상 채팅은 서버가 정보 흐름 전송에 참여하지 않는 P2P 영상 채팅입니다. 정보는 사용자의 브라우저(피어) 간에 직접 전송됩니다. 추가 프로그램. 브라우저 외에도 p2p 화상 채팅은 사용자를 등록하고 사용자에 대한 데이터를 저장하며 사용자 간 전환을 보장하도록 설계된 연락처 서버를 사용합니다. 최신 WebRTC 및 HTML5 기술을 지원하는 브라우저는 IP 네트워크를 통한 음성 및 영상 통신뿐만 아니라 인스턴트 문자 메시지 및 파일 전송도 제공합니다.

따라서 웹 인터페이스의 채팅, 웹 채팅, 음성 및 영상 채팅, IMS, VoIP는 복합 패킷 교환 네트워크를 통해 온라인 통신을 제공하는 서비스입니다. 일반적으로 통신 서비스를 이용하려면 사용자 장치(PC, 스마트폰 등)에 클라이언트 애플리케이션을 설치하거나 브라우저에 플러그인 및 확장 프로그램을 설치해야 합니다. 서비스에는 자체 통신 네트워크가 있으며 대부분은 클라이언트-서버 아키텍처를 기반으로 구축됩니다.

통신 서비스는 음성, 영상, 데이터, 문자 채널이 통합되지 않은 IMS 이외의 애플리케이션입니다. 각 서비스의 네트워크에서는 . 이러한 애플리케이션은 여러 통신 네트워크에서 동시에 작동할 수 없습니다. 일반적으로 애플리케이션은 서로 통신할 수 없으므로 각 통신 네트워크마다 별도의 애플리케이션을 설치해야 합니다.

실시간 커뮤니케이션 서비스(채팅, 전화, 화상회의)를 통합하는 문제, 즉 음성, 비디오, 데이터 채널의 통합과 하나의 애플리케이션(브라우저)을 사용한 액세스는 WebRTC 프로토콜을 기반으로 하는 P2P 또는 P2P 비디오 채팅(P2P, 지점 간)으로 해결할 수 있습니다. 기본적으로 WebRTC를 지원하는 브라우저는 모든 사용자 장치(PC, 스마트폰, iPad, IP 전화, 휴대 전화등) 통신 서비스와 함께 작동합니다.

실시간 통신을 제공하는 모든 기술의 브라우저 구현을 보장하는 것은 WebRTC입니다. P2P 영상채팅의 본질은 서버나 추가 프로그램의 참여 없이 멀티미디어와 텍스트 데이터가 사용자의 브라우저 간에 직접 전송(리모트 피어링)된다는 것입니다. 따라서 브라우저는 거의 모든 것에 대한 액세스를 제공할 뿐만 아니라 정보 자원서버에 저장되어 있을 뿐만 아니라 모든 실시간 통신 서비스 및 메일 서비스(음성 메일, 이메일, SMS 등)

P2P 화상 채팅 서버(연락처 서버)는 사용자 등록, 사용자에 대한 데이터 저장, 사용자 브라우저 간 연결 설정(전환)에만 사용됩니다. 최초의 p2p 화상 채팅은 플래시 기술을 사용하여 구현되었습니다. 예를 들어 Flash P2P 영상 채팅은 다음과 같은 경우에 사용됩니다. 소셜 네트워크에서. 플래시 P2P 영상 채팅은 제공되지 않습니다 고품질멀티미디어 데이터 전송. 또한 P2P 플래시 화상 채팅에서 마이크와 비디오 카메라의 음성 및 비디오 스트림을 출력하려면 설치가 필요합니다. 플래시 플러그인웹 브라우저로.

그러나 차세대 통신 서비스에는 WebRTC 프로토콜과 HTML5 사양을 지원하는 브라우저와 연락처 서버만 사용하여 인터넷을 통해 통신하는 웹 통신이 포함됩니다. 이러한 브라우저가 장착된 모든 사용자 장치(PC, iPad, 스마트폰 등)는 고품질 음성 및 영상 통화는 물론 인스턴트 문자 메시지 및 파일 전송을 제공할 수 있습니다.

따라서 웹 통신(p2p 채팅, 영상 채팅)을 위한 새로운 기술은 WebRTC 프로토콜입니다. WebRTC는 HTML5, CSS3 및 JavaScript와 함께 다양한 웹 애플리케이션을 만들 수 있습니다. WebRT는 P2P 아키텍처를 사용하여 실시간으로 웹 통신(P2P 네트워크)을 구성하도록 설계되었습니다. WebRTC 기반의 P2P 채팅은 브라우저에 있는 외부 추가 기능이나 플러그인을 사용하지 않고 웹 브라우저만 사용하여 인터넷을 통해 사용자 간의 텍스트, 음성 및 영상 통신은 물론 파일 전송도 제공합니다.

P2P 채팅에서 서버는 두 브라우저 간의 P2P 연결을 설정하는 데에만 사용됩니다. WebRTC 프로토콜을 기반으로 p2p 채팅의 클라이언트 부분을 생성하려면 HTML5, CSS3 및 JavaScript가 사용됩니다. 클라이언트 애플리케이션은 WebRTC API를 통해 브라우저와 상호 작용합니다.

WebRTC는 세 가지 JavaScript API로 구현됩니다.

  • RTCPeerConnection;
  • MediaStream(getUserMedia);
  • RTCDataChannel.

브라우저는 UDP 위에서 실행되는 SRTP 프로토콜을 사용하여 미디어 데이터를 전송합니다. NAT는 인터넷을 통해 p2p 연결을 사용하는 NAT 라우터 뒤의 브라우저(클라이언트)에 문제를 일으키기 때문에 STUN은 NAT 변환기를 우회하는 데 사용됩니다. STUN은 UDP 전송 프로토콜 위에서 실행되는 클라이언트-서버 프로토콜입니다. P2P 채팅에서는 일반적으로 공개 STUN 서버가 사용되며, 이 서버에서 수신된 정보는 NAT 뒤에 있는 두 브라우저 간의 UDP 연결에 사용됩니다.

WebRTC 애플리케이션 구현의 예(p2p 채팅, 음성 및 영상 웹 채팅):
1. WebRTC 기반의 P2P 영상채팅 Bistri(원클릭 영상채팅, p2p채팅)를 Bistri에서 오픈할 수 있습니다. Bistri는 추가 프로그램과 플러그인을 설치하지 않고도 브라우저에서 작동합니다. 작업의 본질은 다음과 같습니다. 지정된 링크를 사용하여 p2p 영상 채팅을 열고, 열리는 인터페이스에 등록한 후 파트너를 초대한 다음 피어 클라이언트 목록에서 온라인에 있는 파트너를 선택하고 "영상 통화"를 클릭합니다. "버튼.

결과적으로 MediaStream(getUserMedia)은 마이크 + 웹캠을 캡처하고 서버는 선택한 파트너와 신호 메시지를 교환합니다. 신호 메시지를 교환한 후 PeerConnection API는 음성 및 비디오 스트림을 전송하기 위한 채널을 생성합니다. 또한 Bistri는 인스턴트 문자 메시지와 파일을 전송합니다. 그림에서. 그림 1은 Bistri p2p 영상 채팅 인터페이스의 스크린샷을 보여줍니다.


쌀. 1. P2P 영상채팅 비스트리

2. Twelephone(p2p 영상 채팅, p2p 채팅, SIP Twelephone) - 이 클라이언트 애플리케이션은 HTML5 및 WebRTC를 기반으로 구축되어 음성 및 영상 통화는 물론 인스턴트 문자 메시지도 보낼 수 있습니다. Twelephone에는 테스트 p2p 채팅, 비디오 채팅 및 SIP Twelephone이 포함되어 있습니다. Twelephone은 SIP 프로토콜을 지원하므로 이제 Twitter 계정을 전화번호로 사용하여 SIP 전화에서 음성 및 영상 통화를 걸고 받을 수 있습니다. 게다가, 문자 메시지마이크를 통해 음성으로 입력할 수 있으며, 음성 인식 프로그램은 "메시지 보내기" 줄에 텍스트를 입력합니다.

Twelephone은 브라우저 기반의 웹 전화 통신입니다. 구글 크롬, 버전 25부터 추가 없이 소프트웨어. Twelephone은 Chris Matthieu가 개발했습니다. Twelephone 백엔드는 Node.js를 기반으로 구축되었습니다. 서버(연락처 서버)는 두 브라우저 또는 WebRTC 클라이언트 간에 p2p 연결을 설정하는 데에만 사용됩니다. Twelephone 애플리케이션에는 자체 인증 도구가 없지만 계정 연결에 중점을 둡니다( 계정) 트위터에서.

그림에서. 그림 2는 Twelephone p2p 영상 채팅 인터페이스의 스크린샷을 보여줍니다.



쌀. 2. P2P 텔레폰

3. 그룹 p2p 영상 채팅 Conversat.io는 최신 WebRTC 및 HTML5 기술을 기반으로 구축되었습니다. Conversat 비디오 채팅은 SimpleWebRTC 라이브러리를 기반으로 개발되었으며 한 방에서 최대 6명의 피어 클라이언트 간의 통신을 위해 고안되었습니다(통신을 위해 "대화 이름 지정" 줄에 피어 클라이언트의 휴게실 이름을 표시). P2P 영상채팅 Conversat은 컨택서버에 등록하지 않고도 사용자에게 커뮤니케이션 서비스를 제공합니다. 그림에서. 그림 3은 Conversat p2p 영상 채팅 인터페이스의 스크린샷을 보여줍니다.



쌀. 3. 그룹 P2P 화상 채팅 Conversat.io

WebRTC 기반 P2P 영상 채팅에 참여하려면 사용자는 WebRTC 프로토콜과 HTML5 사양을 지원하는 브라우저가 설치되어 있어야 합니다. 현재 Google Chrome 브라우저는 버전 25부터 모질라 파이어 폭스 Nightly는 WebRTC 프로토콜과 HTML5 사양을 지원합니다. WebRTC 애플리케이션은 이미지 및 사운드 전송 품질 측면에서 Flash 애플리케이션보다 우수합니다.

WebRTC에 관한 대부분의 자료는 코딩의 응용 수준에 초점을 맞추고 있으며 기술 이해에 기여하지 않습니다. 더 깊이 들어가 연결이 어떻게 발생하는지, 세션 설명자와 후보가 무엇인지, STUN 및 TURN 서버가 필요한 이유를 알아 보겠습니다.

WebRTC 소개

WebRTC는 비디오 데이터 전송을 위해 두 클라이언트를 연결할 수 있는 브라우저 중심 기술입니다. 주요 기능은 내부 브라우저 지원(Adobe Flash와 같은 타사 구현 기술이 필요 없음)과 추가 서버를 사용하지 않고 클라이언트를 연결하는 기능인 P2P 연결(이하 P2P)입니다.

컴퓨터에 항상 공용 IP 주소, 즉 인터넷 주소가 있는 것은 아니기 때문에 p2p 연결을 설정하는 것은 다소 어려운 작업입니다. IPv4 주소 수가 적기 때문에(그리고 보안 목적으로) NAT 메커니즘이 개발되었습니다. 이를 통해 가정용 등의 개인 네트워크를 만들 수 있습니다. 이제 많은 홈 라우터가 NAT를 지원하므로 인터넷 공급자는 일반적으로 하나의 IP 주소를 제공하지만 모든 홈 장치는 인터넷에 액세스할 수 있습니다. 공용 IP 주소는 인터넷에서 고유하지만 개인 IP 주소는 그렇지 않습니다. 따라서 p2p 연결이 어렵습니다.

이를 더 잘 이해하려면 세 가지 상황을 고려하십시오. 두 노드가 모두 동일한 네트워크에 있고(그림 1), 두 노드가 서로 다른 네트워크에 있고(하나는 프라이빗, 다른 하나는 퍼블릭)(그림 2) 두 노드가 서로 다른 프라이빗 네트워크에 있습니다. 동일한 IP 주소(그림 3).

그림 1: 동일한 네트워크에 있는 두 노드

그림 2: 서로 다른 네트워크의 노드(하나는 프라이빗, 하나는 퍼블릭)

그림 3: 서로 다른 사설 네트워크에 있지만 숫자상으로는 주소가 동일한 노드

위 그림에서 두 문자 표기법의 첫 번째 문자는 노드 유형(p = 피어, r = 라우터)을 나타냅니다. 첫 번째 그림에서는 상황이 유리합니다. 네트워크의 노드는 네트워크 IP 주소로 완전히 식별되므로 서로 직접 연결할 수 있습니다. 두 번째 그림에는 비슷한 노드 번호를 가진 두 개의 서로 다른 네트워크가 있습니다. 여기에는 두 개의 라우터(라우터)가 나타나는 곳이 있습니다. 네트워크 인터페이스– 네트워크 내부 및 네트워크 외부. 이것이 바로 두 개의 IP 주소를 갖는 이유입니다. 일반 노드에는 네트워크 내에서만 통신할 수 있는 인터페이스가 하나만 있습니다. 네트워크 외부의 누군가에게 데이터를 전송하는 경우 라우터(라우터) 내부의 NAT만 사용하므로 라우터의 IP 주소를 사용하는 다른 사람에게 표시됩니다. 이는 해당 사람의 것입니다. 외부 IP 주소. 따라서 노드 p1은 내부 IP = 192.168.0.200 그리고 외부 IP = 10.50.200.5 , 마지막 주소는 네트워크의 다른 모든 노드 외부에도 있습니다. 상황은 노드 p2에서도 비슷합니다. 따라서 내부(자체) IP 주소만 사용하면 통신이 불가능합니다. 외부 주소, 즉 라우터 주소를 사용할 수 있지만, 동일한 사설망의 모든 노드는 동일한 외부 주소를 가지기 때문에 이는 상당히 어렵습니다. 이 문제는 NAT 메커니즘을 사용하여 해결할 수 있습니다.

내부 주소를 통해 노드를 연결하기로 결정하면 어떻게 되나요? 데이터는 네트워크를 떠나지 않습니다. 효과를 높이기 위해 마지막 그림에 표시된 상황을 상상할 수 있습니다. 두 노드 모두 동일한 내부 주소를 갖습니다. 이를 사용하여 통신하면 각 노드는 자체적으로 통신합니다.

WebRTC는 ICE 프로토콜을 사용하여 이러한 문제에 성공적으로 대처하지만 추가 서버(STUN, TURN)를 사용해야 합니다. 이에 대한 자세한 내용은 아래에서 확인하세요.

WebRTC의 두 단계

WebRTC 프로토콜(또는 두 iPhone이 통신하는 경우 간단히 RTC)을 통해 두 노드를 연결하려면 연결을 설정하기 위한 몇 가지 예비 단계를 수행해야 합니다. 이것이 연결 설정의 첫 번째 단계입니다. 두 번째 단계는 비디오 데이터 전송입니다.

WebRTC 기술은 많은 것을 사용하지만 다양한 방법으로통신(TCP 및 UDP)을 수행하고 이들 사이를 유연하게 전환할 수 있는 기술입니다. 연결 데이터를 전송하기 위한 프로토콜이 없습니다.. 두 개의 p2p 노드를 연결하는 것이 그리 쉽지 않기 때문에 놀라운 일은 아닙니다. 그러므로 어느 정도는 필요하다. 추가의 WebRTC와 전혀 관련이 없는 데이터 전송 방법입니다. 소켓 전송, HTTP 프로토콜일 수도 있고, 심지어는 SMTP 프로토콜또는 러시아 포스트. 이 전송 메커니즘 초기의데이터가 호출됩니다 신호. 많은 정보를 전달할 필요가 없습니다. 모든 데이터는 텍스트 형식으로 전송되며 SDP와 Ice Candidate의 두 가지 유형으로 구분됩니다. 첫 번째 유형은 논리적 연결을 설정하는 데 사용되고 두 번째 유형은 물리적 연결을 설정하는 데 사용됩니다. 이에 대한 자세한 내용은 나중에 설명하겠지만 지금은 WebRTC가 다른 노드로 전송해야 하는 일부 정보를 제공한다는 점을 기억하는 것이 중요합니다. 필요한 모든 정보를 전송하자마자 노드가 연결될 수 있으며 더 이상 도움이 필요하지 않습니다. 따라서 우리가 구현해야 하는 신호 메커니즘은 다음과 같습니다. 갈라져, 사용하게 될 것이다 연결되었을 때만, 단, 영상 데이터 전송 시에는 사용되지 않습니다.

이제 첫 번째 단계인 연결 설정 단계를 살펴보겠습니다. 여러 점으로 구성되어 있습니다. 먼저 연결을 시작하는 노드에 대해 이 단계를 살펴본 다음 대기 중인 노드에 대해 살펴보겠습니다.

  • 개시자(발신자):
  • 비디오 데이터 전송 시작 ​​제안(createOffer)
  • SDP SDP 가져오기)
  • 아이스 후보 받기 아이스 후보 )
  • 통화 대기(수신자):
  • 로컬(사용자) 미디어 스트림을 수신하고 전송을 위해 설정(getUserMediaStream)
  • 영상 데이터 전송 시작 ​​제안을 받고 답변 작성(createAnswer)
  • SDP 객체를 수신하고 이를 신호 메커니즘(SDP)을 통해 전달합니다.
  • Ice 후보 개체를 수신하고 신호 메커니즘을 통해 전달합니다(Ice 후보).
  • 원격(외부) 미디어 스트림을 수신하여 화면에 표시(onAddStream)

유일한 차이점은 두 번째 점에 있습니다.

단계가 복잡해 보이지만 실제로는 자신의 미디어 스트림 전송(항목 1), 연결 매개변수 설정(항목 2-4), 다른 사람의 미디어 스트림 수신(항목 5)이라는 세 가지 단계가 있습니다. 가장 어려운 단계는 두 번째 단계입니다. 두 부분으로 구성되어 있기 때문입니다. 물리적그리고 논리적사이. 첫 번째는 나타냅니다. , 한 네트워크 노드에서 다른 네트워크 노드로 이동하려면 패킷이 이동해야 합니다. 두 번째는 나타냅니다 비디오/오디오 매개변수– 사용할 품질, 사용할 코덱.

정신적으로 createOffer 또는 createAnswer 단계는 SDP 및 Ice 후보 객체를 전달하는 단계와 연결되어야 합니다.

기본 엔터티 미디어 스트림(MediaStream)

주요 본질은 미디어 스트림, 즉 비디오 및 오디오 데이터, 사진 및 사운드의 스트림입니다. 미디어 스트림에는 로컬과 원격의 두 가지 유형이 있습니다. 로컬은 입력 장치(카메라, 마이크)로부터 데이터를 수신하고, 원격은 네트워크를 통해 데이터를 수신합니다. 따라서 각 노드에는 로컬 스레드와 원격 스레드가 모두 있습니다. WebRTC에는 스트림을 위한 MediaStream 인터페이스가 있으며 특히 로컬 스트림을 위한 LocalMediaStream 하위 인터페이스도 있습니다. JavaScript에서는 첫 번째만 만날 수 있지만 libjingle을 사용하면 두 번째도 만날 수 있습니다.

WebRTC는 스레드 내에서 다소 혼란스러운 계층 구조를 가지고 있습니다. 각 스트림은 여러 미디어 트랙(MediaTrack)으로 구성될 수 있으며, 이는 다시 여러 미디어 채널(MediaChannel)로 구성될 수 있습니다. 그리고 자체적으로 여러 미디어 스트림이 있을 수도 있습니다.

모든 것을 순서대로 살펴 보겠습니다. 이를 위해 몇 가지 예를 염두에 두겠습니다. 우리가 우리 자신의 비디오뿐만 아니라 우리가 무언가를 쓸 종이가 놓여 있는 테이블의 비디오도 전송하고 싶다고 가정해 봅시다. 두 개의 비디오(us + table)와 하나의 오디오(us)가 필요합니다. 이 데이터는 아마도 서로 약하게 종속되어 있기 때문에 우리와 테이블을 서로 다른 스레드로 나누어야 한다는 것은 분명합니다. 따라서 우리는 두 개의 MediaStream을 가지게 됩니다. 하나는 우리용이고 다른 하나는 테이블용입니다. 첫 번째 데이터에는 비디오와 오디오 데이터가 모두 포함되고 두 번째 데이터에는 비디오만 포함됩니다(그림 4).

그림 4: 두 가지 다른 미디어 스트림. 하나는 우리용, 하나는 우리 테이블용

미디어 스트림에는 최소한 데이터를 포함하는 기능이 포함되어야 한다는 점은 즉시 명백해집니다. 다른 유형- 비디오 및 오디오. 이는 기술에서 고려되므로 각 데이터 유형은 미디어 트랙 MediaTrack을 통해 구현됩니다. 미디어 트랙에는 비디오인지 오디오인지를 결정하는 특별한 속성인 kind 가 있습니다(그림 5).

그림 5: 미디어 스트림은 미디어 트랙으로 구성됩니다.

프로그램에서 모든 일이 어떻게 진행되나요? 두 개의 미디어 스트림을 생성하겠습니다. 그런 다음 두 개의 비디오 트랙과 하나의 오디오 트랙을 만듭니다. 카메라와 마이크에 접근해 봅시다. 각 트랙에 어떤 장치를 사용할지 알려드리겠습니다. 첫 번째 미디어 스트림에 비디오 및 오디오 트랙을 추가하고 두 번째 미디어 스트림에는 다른 카메라의 비디오 트랙을 추가해 보겠습니다.

하지만 연결의 반대쪽 끝에서 미디어 스트림을 어떻게 구별합니까? 이를 위해 각 미디어 스트림에는 스트림 레이블, 이름 등의 레이블 속성이 있습니다(그림 6). 미디어 트랙은 동일한 속성을 갖습니다. 언뜻 보기에는 비디오가 다른 방식으로 사운드와 구별될 수 있는 것처럼 보입니다.

그림 6: 미디어 스트림과 트랙은 레이블로 식별됩니다.

그렇다면 태그를 통해 미디어 트랙을 식별할 수 있다면 왜 우리의 예에서는 하나가 아닌 두 개의 미디어 스트림을 사용해야 할까요? 결국 하나의 미디어 스트림을 전송할 수 있지만 그 안에 다른 트랙을 사용할 수 있습니다. 우리는 미디어 스트림의 중요한 속성에 도달했습니다. 동기화미디어 트랙. 서로 다른 미디어 스트림은 서로 동기화되지 않지만 각 미디어 스트림 내에서는 모든 트랙이 동기화됩니다. 동시에 재생됩니다.

따라서 우리의 말, 얼굴 감정, 종이 조각이 동시에 재생되기를 원한다면 하나의 미디어 스트림을 사용하는 것이 좋습니다. 이것이 그다지 중요하지 않다면 다른 스트림을 사용하는 것이 더 수익성이 높습니다. 그림이 더 부드러워집니다.

전송 중에 일부 트랙을 비활성화해야 하는 경우 미디어 트랙의 활성화 속성을 사용할 수 있습니다.

마지막으로 스테레오 사운드에 대해 생각해 볼 가치가 있습니다. 아시다시피 스테레오 사운드는 두 가지 다른 소리입니다. 그리고 별도로 전송해야 합니다. 이를 위해 MediaChannel이 사용됩니다. 미디어 오디오 트랙에는 많은 채널이 있을 수 있습니다(예: 5+1 오디오가 필요한 경우 6개). 물론 미디어 트랙 내부에도 채널이 있습니다. 동기화됨. 비디오의 경우 일반적으로 하나의 채널만 사용되지만 광고 오버레이 등을 위해 여러 채널을 사용할 수도 있습니다.

요약:우리는 미디어 스트림을 사용하여 비디오 및 오디오 데이터를 전송합니다. 각 미디어 스트림 내에서 데이터가 동기화됩니다. 동기화가 필요하지 않으면 여러 미디어 스트림을 사용할 수 있습니다. 각 미디어 스트림에는 비디오용과 오디오용이라는 두 가지 유형의 미디어 트랙이 있습니다. 일반적으로 트랙은 2개 이하이지만, (대담자와 테이블의) 여러 비디오를 전송해야 하는 경우 트랙이 더 많을 수 있습니다. 각 트랙은 일반적으로 스테레오 사운드에만 사용되는 여러 채널로 구성될 수 있습니다.

가장 간단한 화상 채팅 상황에서는 하나의 로컬 미디어 스트림이 있습니다. 이 스트림은 두 개의 트랙(비디오 트랙과 오디오 트랙)으로 구성되며 각 트랙은 하나의 메인 채널로 구성됩니다. 비디오 트랙은 카메라를 담당하고, 오디오 트랙은 마이크를 담당하며, 미디어 스트림은 두 가지 모두에 대한 컨테이너입니다.

세션 설명자(SDP)

컴퓨터마다 항상 다른 카메라, 마이크, 비디오 카드 및 기타 장비가 있습니다. 그들에게는 많은 옵션이 있습니다. 이 모든 것은 두 네트워크 노드 간의 데이터 미디어 전송을 위해 조정되어야 합니다. WebRTC는 이 작업을 자동으로 수행하고 생성합니다. 특별한 물건– SDP 세션 설명자. 이 객체를 다른 노드에 전달하면 미디어 데이터가 전송될 수 있습니다. 아직 다른 노드와 연결이 없습니다.

이를 위해 모든 신호 메커니즘이 사용됩니다. SDP는 소켓을 통해 전송되거나 사람(전화로 다른 노드에 전달) 또는 Russian Post를 통해 전송될 수 있습니다. 모든 것이 매우 간단합니다. 기성품 SDP가 제공되며 이를 보내야 합니다. 그리고 상대방에서 수신하면 WebRTC 부서로 전달합니다. 세션 설명자는 텍스트로 저장되며 애플리케이션에서 변경할 수 있지만 일반적으로 그럴 필요는 없습니다. 예를 들어 데스크톱 ← 휴대폰 연결 시 원하는 오디오 코덱을 강제로 선택해야 하는 경우가 있습니다.

일반적으로 연결을 설정할 때 URL과 같은 일종의 주소를 지정해야 합니다. 신호 메커니즘을 통해 사용자 자신이 데이터를 대상으로 보내기 때문에 여기서는 이것이 필요하지 않습니다. p2p 연결을 설정하고 싶다는 것을 WebRTC에 나타내려면 createOffer 함수를 호출해야 합니다. 이 함수를 호출하고 특수 콜백 'a를 지정한 후 SDP 객체가 생성되어 동일한 콜백에 전달됩니다. 귀하에게 필요한 것은 이 개체를 네트워크를 통해 다른 노드(대담자)로 전송하는 것뿐입니다. 그 후 데이터는 신호 메커니즘, 즉 SDP 개체를 통해 다른 쪽 끝에 도착합니다. 이 세션 설명자는 이 노드에 외부이므로 유용한 정보를 전달합니다. 이 객체를 수신하는 것은 연결을 시작하라는 신호입니다. 따라서 이에 동의하고 createAnswer 함수를 호출해야 합니다. createOffer와 완전히 유사합니다. 다시 말하지만, 로컬 세션 설명자는 콜백으로 전달되며 신호 메커니즘을 통해 다시 전달되어야 합니다.

다른 사람의 SDP 개체를 받은 후에만 createAnswer 함수를 호출할 수 있다는 점은 주목할 가치가 있습니다. 왜? createAnswer를 호출할 때 생성되는 로컬 SDP 개체는 원격 SDP 개체에 의존해야 하기 때문입니다. 이 경우에만 비디오 설정을 대화 상대의 설정과 조정할 수 있습니다. 또한 로컬 미디어 스트림을 수신하기 전에 createAnswer 및 createOffer를 호출하면 안 됩니다. SDP 객체에 쓸 내용이 없습니다.

WebRTC에는 SDP 개체를 편집할 수 있는 기능이 있으므로 로컬 설명자를 받은 후 이를 설치해야 합니다. WebRTC가 우리에게 제공한 것을 WebRTC로 전송해야 한다는 것이 조금 이상하게 보일 수도 있지만 이것이 프로토콜입니다. 원격 핸들을 받으면 핸들도 설치해야 합니다. 따라서 하나의 노드에 두 개의 설명자, 즉 자신과 다른 사람의 설명자(즉, 로컬 및 원격)를 설치해야 합니다.

금후 악수노드는 서로의 소망을 알고 있습니다. 예를 들어 노드 1이 코덱 A와 B를 지원하고 노드 2가 코덱 B와 C를 지원하는 경우 각 노드는 자신과 다른 노드의 설명자를 알고 있으므로 두 노드 모두 코덱 B를 선택합니다(그림 7). 이제 연결 로직이 설정되어 미디어 스트림을 전송할 수 있지만 또 다른 문제가 있습니다. 노드는 여전히 신호 메커니즘에 의해서만 연결됩니다.


그림 7: 코덱 협상

아이스 후보

WebRTC 기술은 새로운 방법론으로 우리를 혼란스럽게 만들려고 합니다. 연결을 설정할 때 연결하려는 노드의 주소가 지정되지 않습니다. 먼저 설치됨 논리적연결이 아니라 물리적, 그 반대는 항상 이루어졌지만. 그러나 우리가 제3자 신호 메커니즘을 사용하고 있다는 사실을 잊지 않는다면 이상하게 보이지 않을 것입니다.

따라서 연결은 이미 설정되었지만(논리적 연결) 네트워크 노드가 데이터를 전송할 수 있는 경로는 아직 없습니다. 그렇게 간단하지는 않지만 간단하게 시작해 보겠습니다. 노드가 동일한 개인 네트워크에 있도록 합니다. 우리가 이미 알고 있듯이 내부 IP 주소(또는 TCP/IP가 사용되지 않는 경우 다른 IP 주소)를 사용하여 서로 쉽게 연결할 수 있습니다.

일부 콜백'과 WebRTC를 통해 Ice 후보 객체를 알려줍니다. 또한 텍스트 형식으로도 제공되며 세션 설명자와 마찬가지로 신호 메커니즘을 통해 전송하기만 하면 됩니다. 세션 설명자에 카메라 및 마이크 수준의 설정에 대한 정보가 포함된 경우 후보에는 네트워크에서의 위치에 대한 정보가 포함됩니다. 이를 다른 노드에 전달하면 물리적으로 우리에게 연결할 수 있고 이미 세션 설명자가 있으므로 논리적으로 연결할 수 있고 데이터가 "흐르게" 됩니다. 그가 자신의 후보 객체, 즉 그 자신이 네트워크에서 어디에 있는지에 대한 정보를 우리에게 보내는 것을 기억한다면 우리는 그와 연결할 수 있을 것입니다. 여기서 고전적인 클라이언트-서버 상호 작용과의 차이점을 한 가지 더 살펴보겠습니다. HTTP 서버와의 통신은 요청-응답 방식에 따라 이루어지며 클라이언트는 서버로 데이터를 보내고 서버는 이를 처리한 후 다음을 통해 보냅니다. 요청 패킷에 지정된 주소. WebRTC에서 알아야 할 사항 두 개의 주소그리고 양쪽을 연결해주세요.

세션 설명자와의 차이점은 원격 후보만 설치하면 된다는 것입니다. 여기에서 편집하는 것은 금지되어 있으며 어떠한 이익도 가져올 수 없습니다. 일부 WebRTC 구현에서는 세션 설명자가 설정된 후에만 후보를 설치해야 합니다.

세션 설명자는 하나뿐인데 후보는 많을 수 있는 이유는 무엇입니까? 네트워크의 위치는 내부 IP 주소뿐만 아니라 라우터의 외부 주소(반드시 하나만은 아님)와 TURN 서버의 주소에 의해서도 결정될 수 있기 때문입니다. 단락의 나머지 부분에서는 후보자에 대한 자세한 논의와 다양한 사설 네트워크의 노드를 연결하는 방법에 대해 설명합니다.

따라서 두 개의 노드가 동일한 네트워크에 있습니다(그림 8). 어떻게 식별하나요? IP 주소를 사용합니다. 다른 방법은 없습니다. 사실, 여전히 다른 전송(TCP 및 UDP)과 다른 포트를 사용할 수 있습니다. 이는 IP, PORT, TRANSPORT 등 후보 개체에 포함된 정보입니다. 예를 들어 UDP 전송 및 포트 531을 사용하겠습니다.

그림 8: 두 노드가 동일한 네트워크에 있음

그런 다음 노드 p1에 있으면 WebRTC는 그러한 후보 개체를 제공합니다. 이는 정확한 형식이 아니며 단지 다이어그램일 뿐입니다. 우리가 노드 p2에 있다면 후보는 입니다. 신호 메커니즘을 통해 p1은 p2의 후보(즉, 노드 p2의 위치, 즉 IP 및 PORT)를 수신합니다. 그러면 p1은 p2에 직접 연결할 수 있습니다. 보다 정확하게는 p1이 p2에 도달할 것이라는 희망으로 10.50.150.3:531에 데이터를 보냅니다. 이 주소가 노드 p2에 속하는지 아니면 일부 중개자에 속하는지는 중요하지 않습니다. 유일한 중요한 점은 데이터가 이 주소를 통해 전송되고 p2에 도달할 수 있다는 것입니다.

노드가 동일한 네트워크에 있는 한 모든 것이 간단하고 쉽습니다. 각 노드에는 후보 개체가 하나만 있습니다(항상 자신의 위치, 즉 네트워크에서의 위치를 ​​의미함). 하지만 노드가 활성화되면 더 많은 후보자가 있을 것입니다. 다른네트워크.

좀 더 복잡한 사례로 넘어 갑시다. 한 노드는 라우터 뒤에(보다 정확하게는 NAT 뒤에) 위치하며, 두 번째 노드는 이 라우터와 동일한 네트워크(예: 인터넷)에 위치합니다(그림 9).

그림 9: 한 노드는 NAT 뒤에 있고 다른 노드는 NAT 뒤에 있습니다.

이 사례에는 문제에 대한 특별한 해결책이 있으며 이제 이를 고려해 보겠습니다. 홈 라우터일반적으로 NAT 테이블을 포함합니다. 이는 라우터의 개인 네트워크 내부 노드가 웹 사이트 등에 액세스할 수 있도록 설계된 특수 메커니즘입니다.

웹 서버가 인터넷에 직접 연결되어 있다고 가정해 보겠습니다. 즉, 공용 IP * 주소를 가지고 있습니다. 이것을 노드 p2라고 합시다. 노드 p1(웹 클라이언트)은 주소 10.50.200.10으로 요청을 보냅니다. 먼저, 데이터는 라우터 r1 또는 라우터 r1로 이동합니다. 내부인터페이스 192.168.0.1. 그런 다음 라우터는 소스 주소(주소 p1)를 기억하고 이를 특수 NAT 테이블에 입력한 다음 소스 주소를 자신의 주소로 변경합니다(p1 → r1). 더 나아가 나만의 방식으로 외부인터페이스에서는 라우터가 데이터를 p2 웹 서버로 직접 보냅니다. 웹 서버는 데이터를 처리하고 응답을 생성하여 다시 보냅니다. r1이 반환 주소에 있으므로 라우터로 보냅니다(라우터는 주소를 자체 주소로 대체했습니다). 라우터는 데이터를 수신하고 NAT 테이블을 확인한 후 노드 p1에 데이터를 전달합니다. 여기서 라우터는 중개자 역할을 합니다.

내부 네트워크의 여러 노드가 동시에 외부 네트워크에 접속한다면 어떻게 될까요? 라우터는 응답을 누구에게 다시 보낼지 어떻게 이해합니까? 이 문제는 다음을 사용하여 해결됩니다. 포트. 라우터가 호스트 주소를 자신의 주소로 교체하면 포트도 교체됩니다. 두 노드가 인터넷에 액세스하면 라우터는 해당 소스 포트를 다음으로 대체합니다. 다른. 그런 다음 웹 서버의 패킷이 라우터로 돌아오면 라우터는 패킷이 할당된 포트를 통해 이해하게 됩니다. 아래 예.

WebRTC 기술, 더 정확하게는 ICE 프로토콜을 사용하는 부분(따라서 Ice 후보)으로 돌아가 보겠습니다. 노드 p2에는 하나의 후보(네트워크에서의 위치는 10.50.200.10)가 있고 NAT가 있는 라우터 뒤에 있는 노드 p1에는 로컬 후보(192.168.0.200)와 라우터 후보(10.50.200.5)라는 두 개의 후보가 있습니다. 첫 번째는 유용하지 않지만 그럼에도 불구하고 WebRTC는 원격 노드에 대해 아직 아무것도 모르기 때문에 생성됩니다. 동일한 네트워크에 있을 수도 있고 아닐 수도 있습니다. 두 번째 후보가 유용할 것이며 이미 알고 있듯이 포트(NAT를 통과하기 위한)가 중요한 역할을 할 것입니다.

NAT 테이블의 항목은 데이터가 내부 네트워크를 떠날 때만 생성됩니다. 따라서 노드 p1은 먼저 데이터를 전송해야 하며 그 후에만 노드 p2의 데이터가 노드 p1에 도달할 수 있습니다.

연습 중 두 노드 모두 NAT 뒤에 있을 것입니다. 각 라우터의 NAT 테이블에 항목을 생성하려면 호스트는 원격 호스트에 무언가를 보내야 하지만 이번에는 전자가 후자에 도달할 수 없고 그 반대도 마찬가지입니다. 이는 노드가 자신의 외부 IP 주소를 모르기 때문에 내부 주소로 데이터를 보내는 것이 의미가 없기 때문입니다.

그러나 외부 주소를 알면 연결이 쉽게 설정됩니다. 첫 번째 노드가 두 번째 노드의 라우터로 데이터를 보내면 라우터는 NAT 테이블이 여전히 비어 있으므로 이를 무시합니다. 그러나 첫 번째 노드의 라우터에서는 NAT 테이블에 필요한 항목이 나타났습니다. 이제 두 번째 노드가 첫 번째 노드의 라우터로 데이터를 전송하면 라우터는 해당 데이터를 첫 번째 노드로 성공적으로 전송합니다. 이제 두 번째 라우터의 NAT 테이블에도 필요한 데이터가 있습니다.

문제는 외부 IP 주소를 찾으려면 다음 위치에 있는 노드가 필요하다는 것입니다. 공유 네트워크. 이 문제를 해결하기 위해 인터넷에 직접 연결된 추가 서버가 사용됩니다. 이들의 도움으로 NAT 테이블에도 소중한 항목이 생성됩니다.

STUN 및 TURN 서버

WebRTC를 초기화할 때 사용 가능한 STUN 및 TURN 서버를 지정해야 하며, 이후에는 이를 ICE 서버라고 부릅니다. 서버가 지정되지 않으면 동일한 네트워크(NAT 없이 연결된)의 노드만 연결할 수 있습니다. 3g 네트워크의 경우 TURN 서버 사용이 필수라는 점은 즉시 주목할 가치가 있습니다.

충격 섬기는 사람반환 주소, 즉 보낸 사람 노드의 주소를 반환하는 인터넷의 서버일 뿐입니다. 라우터 뒤에 있는 호스트는 NAT를 통과하기 위해 STUN 서버에 접속합니다. STUN 서버로 온 패킷에는 소스 주소, 즉 라우터 주소, 즉 노드의 외부 주소가 포함되어 있습니다. 서버가 다시 보내는 STUN 주소입니다. 따라서 노드는 외부 IP 주소와 네트워크에서 액세스할 수 있는 포트를 받습니다. 다음으로 WebRTC는 이 주소를 사용하여 추가 후보(외부 라우터 주소 및 포트)를 생성합니다. 이제 필요한 포트의 라우터로 전송된 패킷이 노드에 도달하도록 허용하는 항목이 라우터의 NAT 테이블에 있습니다.

예를 들어 이 과정을 살펴보겠습니다.

예시(STUN 서버 운영)

STUN 서버는 s1로 표시됩니다. 이전과 마찬가지로 라우터는 r1을 통해 연결되고 노드는 p1을 통해 연결됩니다. NAT 테이블도 모니터링해야 합니다. 이를 r1_nat로 표시하겠습니다. 또한 이 테이블에는 일반적으로 서브넷의 여러 노드에서 가져온 많은 레코드가 포함되어 있으므로 제공되지 않습니다.

따라서 처음에는 빈 테이블 r1_nat이 있습니다.

표 2: 패킷 헤더

노드 p1은 이 패킷을 라우터 r1로 보냅니다(어쨌든 다른 서브넷은 사용할 수 있음). 다양한 기술). 패킷에 지정된 주소는 분명히 외부 서브넷에 적합하지 않기 때문에 라우터는 소스 주소 Src IP를 대체해야 하며, 또한 해당 범위의 주소는 예약되어 있으며 인터넷의 단일 주소에는 이러한 주소가 없습니다. 라우터는 패킷을 대체하고 다음을 생성합니다. 새로운 항목테이블 r1_nat에 있습니다. 이렇게 하려면 포트 번호를 알아내야 합니다. 서브넷 내의 여러 호스트가 외부 네트워크에 액세스할 수 있으므로 NAT 테이블은 다음을 저장해야 합니다. 추가 정보, 라우터는 이러한 여러 노드 중 어느 노드가 서버의 반환 패킷을 대상으로 하는지 결정할 수 있습니다. 라우터가 포트 888을 생성하도록 합니다.

변경된 패키지 헤더:

표 4: NAT 테이블이 새 항목으로 업데이트되었습니다.

여기서 서브넷의 IP 주소와 포트는 원본 패킷과 정확히 동일합니다. 실제로 포스트백을 할 때에는 이를 완전히 복원할 수 있는 방법이 있어야 합니다. 외부 네트워크의 IP 주소는 라우터의 주소이며, 포트는 라우터가 발명한 포트로 변경되었습니다.

노드 p1이 연결을 수락하는 실제 포트는 물론 35777이지만 서버는 다음으로 데이터를 보냅니다. 허구의포트 888은 라우터에 의해 실제 35777로 변경됩니다.

따라서 라우터는 패킷 헤더의 소스 주소와 포트를 대체하고 NAT 테이블에 항목을 추가했습니다. 이제 패킷은 네트워크를 통해 서버, 즉 노드 s1으로 전송됩니다. 입력에서 s1에는 다음 패킷이 있습니다.

소스 IP 소스 포트 대상 IP 대상 포트
10.50.200.5 888 12.62.100.200 6000

표 5: STUN 서버 수신 패킷

전체적으로 STUN 서버는 주소 10.50.200.5:888에서 패킷을 수신했음을 알고 있습니다. 이제 서버는 이 주소를 다시 보냅니다. 여기에서 멈춰서 방금 살펴본 내용을 다시 살펴보는 것이 좋습니다. 위의 표는 머리글패키지, 전혀 그것에서 콘텐츠. 내용은 그다지 중요하지 않기 때문에 내용에 대해서는 언급하지 않았습니다. 내용은 STUN 프로토콜에 설명되어 있습니다. 이제 제목 외에 내용도 살펴보겠습니다. 그것은 간단하며 라우터 주소(10.50.200.5:888)를 포함합니다. 머리글패키지. 이는 자주 수행되지 않습니다. 프로토콜은 일반적으로 노드 주소에 대한 정보에 관심이 없으며 패킷이 의도한 대상으로 전달되는 것만 중요합니다. 여기서는 두 노드 사이에 경로를 설정하는 프로토콜을 살펴보겠습니다.

이제 반대 방향으로 가는 두 번째 패킷이 생겼습니다.

표 7: STUN 서버는 이 콘텐츠가 포함된 패킷을 보냅니다.

다음으로, 패킷은 라우터 r1의 외부 인터페이스에 도달할 때까지 네트워크를 통해 이동합니다. 라우터는 패킷이 자신을 위한 것이 아니라는 것을 이해합니다. 그는 이것을 어떻게 이해합니까? 이는 포트에 의해서만 결정될 수 있습니다. 그는 개인적인 목적으로 포트 888을 사용하지 않고 NAT 메커니즘에 사용합니다. 따라서 라우터는 이 테이블을 봅니다. 외부 포트(External PORT) 열을 보고 수신 패킷의 대상 포트(Dest PORT)와 일치하는 라인, 즉 888을 찾습니다.

내부 IP 내부 포트 외부 IP 외부 포트
192.168.0.200 35777 10.50.200.5 888

표 8: NAT 테이블

운이 좋게도 그런 선이 존재합니다. 운이 좋지 않다면 패킷은 그냥 버려질 것입니다. 이제 서브넷의 어느 노드가 이 패킷을 보내야 하는지 이해해야 합니다. 서두를 필요가 없습니다. 이 메커니즘에서 포트의 중요성을 다시 한번 기억해 봅시다. 동시에 서브넷의 두 노드는 외부 네트워크에 요청을 보낼 수 있습니다. 그런 다음 라우터가 첫 번째 노드에 대해 포트 888을 제공하면 두 번째 노드에 대해 포트 889를 제공합니다. 이런 일이 발생했다고 가정해 보겠습니다. 즉, r1_nat 테이블은 다음과 같습니다.

표 10: 라우터는 수신자 주소를 대체합니다.

소스 IP 소스 포트 대상 IP 대상 포트
12.62.100.200 6000 192.168.0.200 35777

표 11: 라우터가 수신자 주소를 변경했습니다.

패킷은 노드 p1에 성공적으로 도착하고, 패킷의 내용을 보고 노드는 자신의 외부 IP 주소, 즉 외부 네트워크의 라우터 주소를 알게 됩니다. 그는 또한 라우터가 NAT를 통과하는 포트를 알고 있습니다.

무엇 향후 계획? 이 모든 것이 다 무슨 소용이 있습니까? 이점은 r1_nat 테이블의 항목입니다. 이제 누군가 포트 888을 사용하여 패킷을 라우터 r1로 보내면 라우터는 이 패킷을 노드 p1로 전달합니다. 이로 인해 숨겨진 노드 p1으로 가는 작고 좁은 통로가 만들어졌습니다.

위의 예를 통해 NAT의 작동 방식과 STUN 서버의 본질에 대한 아이디어를 얻을 수 있습니다. 일반적으로 ICE 메커니즘과 STUN/TURN 서버는 NAT 제한을 극복하는 것을 목표로 합니다.

노드와 서버 사이에는 하나의 라우터가 아니라 여러 개가 있을 수 있습니다. 이 경우 노드는 서버와 동일한 네트워크에 가장 먼저 접속한 라우터의 주소를 받게 됩니다. 즉, STUN 서버에 연결된 라우터의 주소를 가져옵니다. p2p 통신의 경우 각 라우터가 NAT 테이블에 필요한 회선을 추가한다는 사실을 잊지 않는다면 이것이 바로 우리에게 필요한 것입니다. 그러므로 돌아오는 길도 마찬가지로 순조로울 것입니다.

TURN 서버는 향상된 STUN 서버입니다. 여기에서 모든 TURN 서버가 STUN 서버로도 작동할 수 있다는 사실을 즉시 제거해야 합니다. 그러나 장점도 있습니다. P2P 통신이 불가능한 경우(예: 3G 네트워크) 서버는 릴레이 모드로 전환됩니다. 즉, 중개자 역할을 합니다. 물론, 우리는 p2p에 대해 이야기하는 것이 아니지만 ICE 메커니즘 외부에서는 노드가 직접 통신하고 있다고 생각합니다.

어떤 경우에 TURN 서버가 필요합니까? STUN 서버가 부족한 이유는 무엇입니까? 사실 NAT에는 여러 유형이 있습니다. 동일한 방식으로 IP 주소와 포트를 대체하지만 일부에는 "위조"에 대한 추가 보호 기능이 내장되어 있습니다. 예를 들어, 대칭 NAT 테이블에는 원격 노드의 IP와 포트라는 2개의 매개변수가 더 저장됩니다. 외부 네트워크의 패킷은 소스 주소와 포트가 표에 기록된 것과 일치하는 경우에만 NAT를 통해 내부 네트워크로 전달됩니다. 따라서 STUN 서버의 트릭은 실패합니다. NAT 테이블은 STUN 서버의 주소와 포트를 저장하고 라우터가 WebRTC 대담자로부터 패킷을 수신하면 "위조"되었기 때문에 이를 폐기합니다. STUN 서버에서 온 것이 아닙니다.

따라서 두 대담자가 모두 뒤에 있는 경우에는 TURN 서버가 필요합니다. 대칭 NAT(각자 자신에게).

간단한 요약

다음은 항상 염두에 두어야 할 WebRTC 엔터티에 대한 몇 가지 설명입니다. 위에 자세히 설명되어 있습니다. 진술 중 하나라도 완전히 명확하지 않은 경우 관련 단락을 다시 읽으십시오.

  • 미디어 스트림
    • 비디오 및 오디오 데이터는 미디어 스트림으로 패키징됩니다.
    • 미디어 스트림은 구성하는 미디어 트랙을 동기화합니다.
    • 서로 다른 미디어 스트림이 서로 동기화되지 않습니다.
    • 미디어 스트림은 로컬 및 원격일 수 있으며, 로컬 스트림은 일반적으로 카메라와 마이크에 연결되고, 원격 스트림은 암호화된 형식으로 네트워크에서 데이터를 수신합니다.
    • 미디어 트랙에는 비디오용과 오디오용의 두 가지 유형이 있습니다.
    • 미디어 트랙에는 켜기/끄기 기능이 있습니다.
    • 미디어 트랙은 미디어 채널로 구성됩니다.
    • 미디어 트랙은 구성하는 미디어 채널을 동기화합니다.
    • 미디어 스트림과 미디어 트랙에는 구별할 수 있는 레이블이 있습니다.
  • 세션 핸들
    • 세션 설명자는 두 개의 네트워크 노드를 논리적으로 연결하는 데 사용됩니다.
    • 세션 설명자는 다음에 대한 정보를 저장합니다. 사용 가능한 방법비디오 및 오디오 데이터 인코딩
    • WebRTC는 외부 신호 메커니즘을 사용합니다. 세션 설명자(sdp) 전달 작업은 애플리케이션에 속합니다.
    • 논리적 연결 메커니즘은 제안(제안)과 응답(응답)의 두 단계로 구성됩니다.
    • 제안의 경우 로컬 미디어 스트림을 사용하지 않으면 세션 설명자 생성이 불가능하고 답변의 경우 원격 세션 설명자를 사용하지 않으면 불가능합니다.
    • 결과 설명자는 WebRTC 구현에 제공되어야 하며 이 설명자가 동일한 WebRTC 구현에서 원격으로 수신되는지 아니면 로컬로 수신되는지는 중요하지 않습니다.
    • 세션 설명자를 약간 편집할 수 있습니다.
  • 후보자
    • Ice Candidate는 네트워크에 있는 노드의 주소입니다.
    • 노드 주소는 자신의 주소이거나 라우터 또는 TURN 서버의 주소일 수 있습니다.
    • 항상 후보자가 많다.
    • 후보는 IP 주소, 포트 및 전송 유형(TCP 또는 UDP)으로 구성됩니다.
    • 후보자는 네트워크의 두 노드 사이에 물리적 연결을 설정하는 데 사용됩니다.
    • 또한 후보자는 신호 메커니즘을 통해 전송되어야 합니다.
    • 후보자도 WebRTC 구현으로 전달되어야 하지만 원격 구현에만 전달되어야 합니다.
    • 일부 WebRTC 구현에서는 세션 설명자가 설정된 후에만 후보를 전송할 수 있습니다.
  • 기절/회전/얼음/NAT
    • NAT는 외부 네트워크에 대한 액세스를 제공하는 메커니즘입니다.
    • 홈 라우터는 특수 NAT 테이블을 지원합니다.
    • 라우터는 패킷의 주소를 대체합니다. 즉, 패킷이 외부 네트워크로 이동하는 경우 소스 주소를 자체 주소로 바꾸고, 패킷이 외부 네트워크에서 제공된 경우 수신자 주소를 내부 네트워크의 호스트 주소로 바꿉니다.
    • 외부 네트워크에 대한 다중 채널 액세스를 제공하기 위해 NAT는 포트를 사용합니다.
    • ICE - NAT 통과 엔진
    • STUN 및 TURN 서버 – NAT 통과를 위한 보조 서버
    • STUN 서버를 사용하면 NAT 테이블에 필요한 항목을 생성하고 호스트의 외부 주소도 반환할 수 있습니다.
    • TURN 서버는 STUN 메커니즘을 일반화하고 항상 작동하도록 만듭니다.
    • 최악의 경우에는 TURN 서버가 중개자(릴레이)로 사용됩니다. 즉, p2p가 클라이언트-서버-클라이언트 연결로 전환됩니다.

오늘날 WebRTC는 브라우저에서 오디오 및 비디오 스트리밍을 위한 "인기" 기술입니다. HTTP 스트리밍 및 플래시와 같은 보수적인 기술은 녹화된 콘텐츠(주문형 비디오) 배포에 더 적합하며 실시간 및 온라인 방송 측면에서 WebRTC보다 훨씬 열등합니다. 시청자가 무슨 일이 일어나고 있는지 '실시간'으로 볼 수 있으려면 최소한의 비디오 대기 시간이 필요합니다.

고품질 실시간 통신의 가능성은 UDP 프로토콜을 사용하여 비디오 스트림을 전송하는 WebRTC 아키텍처 자체에서 비롯됩니다. 이는 최소한의 지연으로 비디오를 전송하기 위한 표준 기반이며 실시간 통신 시스템에서 널리 사용됩니다.

통신 대기 시간은 비디오 소스, 최종 사용자와의 대화형 통신이 필요하고 솔루션이 필요한 온라인 방송 시스템, 웹 세미나 및 기타 애플리케이션에서 중요합니다.

WebRTC를 시도하는 또 다른 좋은 이유는 그것이 확실히 추세라는 것입니다. 오늘은 모든 안드로이드 크롬 브라우저추가 소프트웨어나 구성을 설치하지 않고도 수백만 대의 장치에서 방송을 시청할 수 있도록 보장하는 이 기술을 지원합니다.

WebRTC 기술을 실제로 테스트하고 간단한 실행을 위해 온라인 방송, 우리는 Flashphoner WebRTC 미디어 및 방송 서버 서버 소프트웨어를 사용했습니다. 이 기능에는 일대다 모드로 WebRTC 스트림을 브로드캐스트하는 기능과 RTSP 프로토콜을 통한 IP 카메라 및 비디오 감시 시스템 지원이 명시되어 있습니다. 이번 리뷰에서는 웹-웹 방송과 그 특징에 대해 중점적으로 살펴보겠습니다.

WebRTC 미디어 및 방송 서버 설치

때문에 윈도우 시스템서버 버전도 없었고, VMWare+Linux 같은 가상머신도 설치하고 싶지 않았기 때문에 집에서 온라인 방송을 테스트해볼 수 있었습니다. 윈도우 컴퓨터운동하지 않았습니다. 시간을 절약하기 위해 우리는 다음과 같이 클라우드 호스팅에서 인스턴스를 사용하기로 결정했습니다.

암스테르담 데이터센터에 사전 설치된 소프트웨어가 없는 Centos x86_64 버전 6.5였습니다. 따라서 우리가 사용할 수 있는 것은 서버와 이에 대한 SSH 액세스뿐입니다. 잘 아시는 분들을 위해 콘솔 명령 Linux에서는 WebRTC 서버를 설치하는 것이 간단하고 어렵지 않습니다. 그래서 우리가 한 일은:

1. 아카이브를 다운로드합니다:

$wget https://site/download-wcs5-server.tar.gz

2. 포장 풀기:

$tar -xzf 다운로드-wcs5-server.tar.gz

3. 설치:

$cd FlashphonerWebCallServer

설치하는 동안 서버 IP 주소를 입력하세요: XXX.XXX.XXX.XXX

4. 라이센스를 활성화합니다:

$cd /usr/local/FlashphonerWebCallServer/bin

$./activation.sh

5. WCS 서버를 시작합니다:

$service webcall서버 시작

6. 로그를 확인합니다.

$tail - f /usr/local/FlashphonerWebCallServer/logs/flashphoner_manager.log

7. 두 가지 프로세스가 준비되어 있는지 확인합니다.

$ps 보조 | grep 플래쉬폰너

설치 프로세스가 완료되었습니다.

WebRTC 온라인 방송 테스트

방송을 테스트하는 것은 간단한 문제로 판명되었습니다. 서버 외에도 12개의 Javascript, HTML 및 CSS 파일로 구성되고 설치 단계에서 /var/www/html 폴더에 배포된 웹 클라이언트가 있습니다. 수행해야 할 유일한 작업은 서버의 IP 주소를 flashphoner.xml 구성에 입력하여 웹 클라이언트가 HTML5 웹소켓을 통해 서버와 연결을 설정할 수 있도록 하는 것이었습니다. 테스트 과정을 설명하겠습니다.

1. Chrome 브라우저에서 index.html 테스트 클라이언트 페이지를 엽니다.

2. 방송을 시작하려면 화면 중앙의 '시작' 버튼을 클릭해야 합니다.
이 작업을 수행하기 전에 웹캠이 연결되어 있고 사용할 준비가 되었는지 확인해야 합니다. 웹캠에 대한 특별한 요구 사항은 없습니다. 예를 들어 우리는 1280x800 해상도의 노트북에 내장된 표준 카메라를 사용했습니다.

Chrome 브라우저는 사용자가 자신의 비디오가 인터넷 서버로 전송되고 이를 허용한다는 것을 이해할 수 있도록 카메라와 마이크에 대한 액세스를 확실히 요청합니다.

3. 인터페이스는 카메라에서 WebRTC 서버로의 비디오 스트림의 성공적인 브로드캐스트를 나타냅니다. 오른쪽 상단 모서리에 표시기는 스트림이 서버로 가고 있음을 나타내며 하단 모서리에는 비디오 전송을 중지하는 "중지" 버튼이 있습니다.

아래 상자의 링크를 참고하세요. 여기에는 이 스트림에 대한 고유 식별자가 포함되어 있어 누구나 시청에 참여할 수 있습니다. 브라우저에서 이 링크를 열어보세요. 클립보드에 복사하려면 "복사" 버튼을 클릭하세요.

웹 세미나, 강의, 온라인 비디오 방송 또는 대화형 TV와 같은 실제 애플리케이션에서 개발자는 원하는 스트림에 연결할 수 있도록 특정 시청자 그룹에 이 식별자 배포를 구현해야 하지만 이는 이미 애플리케이션의 논리입니다. . WebRTC Media & Broadcasting Server는 영향을 미치지 않으며 비디오 배포만 합니다.

5. 연결이 완료되고 시청자는 화면에서 스트림을 봅니다. 이제 그는 오른쪽 하단에 있는 컨트롤을 사용하여 다른 사람에게 링크를 보내거나, 스트림 재생을 중지하거나, 전체 화면 모드를 활성화할 수 있습니다.

WebRTC 온라인 방송 서버 테스트 결과

테스트하는 동안 대기 시간은 완벽해 보였습니다. 데이터 센터에 대한 핑은 약 100밀리초였으며 지연은 눈에 보이지 않았습니다. 여기에서 실제 지연은 버퍼링 시간에 대해 100 ± 수십 밀리초와 동일하다고 가정할 수 있습니다. Flash 비디오와 비교: 이러한 테스트에서 Flash는 WebRTC만큼 작동하지 않습니다. 그래서 유사한 네트워크에서 손을 움직이면 1~2초 후에야 화면의 움직임을 볼 수 있다.

품질과 관련하여 큐브는 때때로 움직임으로 구별될 수 있습니다. 이는 VP8 코덱의 특성과 주요 목적, 즉 허용 가능한 품질과 통신 지연 없이 실시간 비디오 통신을 제공하는 것과 일치합니다.

서버는 설치 및 구성이 매우 쉽습니다. 서버를 실행하는 데에는 SSH를 통해 콘솔에서 명령을 실행하고 다음을 사용할 수 있는 고급 사용자 수준의 Linux 지식 외에는 심각한 기술이 필요하지 않습니다. 텍스트 에디터. 그 결과, 우리는 브라우저 간 일대다 온라인 브로드캐스트를 설정하는 데 성공했습니다. 추가 시청자를 스트림에 연결해도 문제가 발생하지 않았습니다.

방송 품질은 웨비나 및 온라인 방송에 매우 적합한 것으로 나타났습니다. 몇 가지 의문을 제기한 유일한 것은 비디오 해상도였습니다. 카메라는 1280x800을 지원하지만 테스트 이미지의 해상도는 640x480과 매우 유사합니다. 분명히 이 문제는 개발자들과 함께 명확히 해야 할 것 같습니다.

웹캠에서 브로드캐스트 테스트에 대한 비디오
WebRTC 서버를 통해

브라우저에서 호출을 수행하는 기술은 Java, ActiveX, 어도비 플래시...지난 몇 년 동안 플러그인과 가상 머신편리함(왜 아무것도 설치해야 합니까?)과 가장 중요하게는 보안이 뛰어나지 않습니다. 무엇을 해야 할까요? 출구가 있습니다!

최근까지 IP 네트워크는 IP 전화 통신 또는 비디오에 여러 프로토콜을 사용했습니다. 가장 일반적인 프로토콜인 SIP, H.323 및 MGCP, Jabber/Jingle(Gtalk에서 사용됨), 반 개방형 Adobe RTMP* 및 물론 , Skype를 종료했습니다. Google이 시작한 WebRTC 프로젝트는 IP 및 웹 전화 통신 세계의 상황을 바꾸려고 노력하고 있습니다. 소프트폰, 스카이프 포함. WebRTC는 현재 거의 모든 기기에 설치되어 있는 브라우저 내에서 모든 통신 기능을 직접 구현할 뿐만 아니라, 브라우저 사용자 간 통신의 보다 일반적인 문제(다양한 데이터 교환, 화면 브로드캐스팅, 문서와의 협업, 훨씬 더).

웹 개발자의 관점에서 본 WebRTC

웹 개발자의 관점에서 WebRTC는 두 가지 주요 부분으로 구성됩니다.

  • 로컬 리소스(카메라, 마이크 또는 화면)에서 미디어 스트림 제어 로컬 컴퓨터)은 MediaStream 객체를 반환하는 navigator.getUserMedia 메소드에 의해 구현됩니다.
  • 통신 방법 정의 및 직접 전송을 포함하여 미디어 스트림을 생성하는 장치 간의 P2P 통신 - RTCPeerConnection 객체(오디오 및 비디오 스트림 전송 및 수신용) 및 RTCDataChannel(브라우저에서 데이터 전송 및 수신용).
우리는 무엇을해야합니까?

웹 소켓을 사용하여 WebRTC 기반 브라우저 간에 간단한 다중 사용자 영상 채팅을 구성하는 방법을 알아 보겠습니다. WebRTC 측면에서 가장 진보된 브라우저인 Chrome/Chromium에서 실험을 시작할 것입니다. 하지만 6월 24일에 출시된 Firefox 22가 이를 거의 따라잡았습니다. 표준은 아직 채택되지 않았으며 API는 버전마다 변경될 수 있습니다. 모든 예제는 Chromium 28에서 테스트되었습니다. 단순화를 위해 코드의 정확성과 브라우저 간 호환성을 모니터링하지 않습니다.

미디어스트림

첫 번째이자 가장 간단한 WebRTC 구성 요소는 MediaStream입니다. 이를 통해 브라우저는 로컬 컴퓨터의 카메라 및 마이크에서 미디어 스트림에 액세스할 수 있습니다. Chrome에서는 이를 위해 navigator.webkitGetUserMedia() 함수를 호출해야 합니다(표준이 아직 확정되지 않았기 때문에 모든 함수에는 접두사가 있고 Firefox에서는 동일한 함수가 navigator.mozGetUserMedia()라고 함). 호출하면 사용자에게 카메라와 마이크에 대한 액세스를 허용하라는 메시지가 표시됩니다. 사용자가 동의한 후에만 통화를 계속할 수 있습니다. 필요한 미디어 스트림의 매개변수와 두 개의 콜백 함수가 이 함수에 매개변수로 전달됩니다. 첫 번째는 카메라/마이크에 대한 액세스가 성공적으로 획득되면 호출되고 두 번째는 오류가 발생하는 경우 호출됩니다. 먼저 버튼과 요소가 포함된 HTML 파일 rtctest1.html을 만들어 보겠습니다.

WebRTC - 첫 번째 소개 영상( 높이: 240px; 너비: 320px; 테두리: 1px 단색 회색; ) getUserMedia

Microsoft CU-RTC-웹

CU-RTC-Web(html5labs.interoperabilitybridges.com/cu-rtc-web/cu-rtc-web.html5labs.interoperabilitybridges.com/cu-rtc-web/cu-rtc-web. htm). 이미 적은 IE의 점유율은 계속 감소하고 있지만 Skype 사용자의 수는 Microsoft가 Google을 대체할 수 있는 희망을 주고 있으며 이 특정 표준이 브라우저에서 사용될 것이라고 추측할 수 있습니다. 스카이프 버전. Google 표준은 주로 브라우저 간의 통신에 중점을 두고 있습니다. 동시에, 음성 트래픽의 대부분은 여전히 ​​일반 전화 네트워크에 남아 있으며, IP 네트워크와 IP 네트워크 사이의 게이트웨이는 사용 편의성이나 빠른 배포뿐만 아니라 더 많은 플레이어가 사용할 수 있는 수익 창출 수단으로도 필요합니다. 그들을 개발하십시오. 또 다른 표준의 출현은 개발자가 두 가지 호환되지 않는 기술을 동시에 지원해야 하는 불쾌한 필요성을 초래할 수 있을 뿐만 아니라 앞으로는 사용자에게 가능한 기능과 사용 가능한 기술 솔루션에 대한 더 넓은 선택권을 제공할 수도 있습니다. 기다려 보세요.

로컬 스트림 활성화

HTML 파일의 태그 내에서 미디어 스트림에 대한 전역 변수를 선언해 보겠습니다.

Var localStream = null;

getUserMedia 메소드의 첫 번째 매개변수는 요청된 미디어 스트림의 매개변수를 지정해야 합니다. 예를 들어 간단히 오디오 또는 비디오를 활성화하면 됩니다.

Var streamConstraints = ("audio": true, "video": true); // 오디오와 비디오 모두에 대한 액세스를 요청합니다.

또는 추가 매개변수를 지정합니다.

Var streamConstraints = ( "audio": true, "video": ( "필수": ( "maxWidth": "320", "maxHeight": "240", "maxFrameRate": "5"), "선택 사항": ) );

getUserMedia 메소드에 대한 두 번째 매개변수는 콜백 함수에 전달되어야 하며, 콜백 함수는 성공할 경우 호출됩니다.

Function getUserMedia_success(stream) ( console.log("getUserMedia_success():", stream); localVideo1.src = URL.createObjectURL(stream); // 미디어 스트림을 HTML 요소 localStream = stream; // 연결하고 저장합니다. 추가 사용을 위해 전역 변수에)

세 번째 매개변수는 오류 발생 시 호출되는 오류 핸들러인 콜백 함수입니다.

함수 getUserMedia_error(error) ( console.log("getUserMedia_error():", error); )

getUserMedia 메소드에 대한 실제 호출은 첫 번째 버튼을 눌렀을 때 마이크 및 카메라에 대한 액세스를 요청하는 것입니다.

함수 getUserMedia_click() ( console.log("getUserMedia_click()"); navigator.webkitGetUserMedia(streamConstraints, getUserMedia_success, getUserMedia_error); )

로컬로 열린 파일에서는 미디어 스트림에 액세스할 수 없습니다. 이 작업을 시도하면 다음과 같은 오류가 발생합니다.

NavigatorUserMediaError(코드: 1, PERMISSION_DENIED: 1)"

결과 파일을 서버에 업로드하고, 브라우저에서 열고, 나타나는 요청에 응답하여 카메라와 마이크에 대한 액세스를 허용해 보겠습니다.

설정, 고급 설정 링크 표시, 개인정보 보호 섹션, 콘텐츠 버튼에서 Chrome이 액세스할 수 있는 기기를 선택할 수 있습니다. Firefox 및 Opera 브라우저에서는 액세스가 허용되면 드롭다운 목록에서 장치가 직접 선택됩니다.

HTTP 프로토콜을 사용하는 경우 페이지가 로드된 후 미디어 스트림에 액세스할 때마다 권한이 요청됩니다. HTTPS로 전환하면 미디어 스트림에 처음 액세스할 때만 요청을 한 번 표시할 수 있습니다.

북마크 아이콘의 진동하는 원과 주소 표시줄 오른쪽의 카메라 아이콘을 확인하세요.

RTCMediaConnection

RTCMediaConnection은 참가자 간 네트워크를 통해 미디어 스트림을 설정하고 전송하도록 설계된 개체입니다. 또한 이 개체는 SDP(미디어 세션 설명) 생성, NAT 통과를 위한 ICE 후보에 대한 정보 획득 또는 방화벽(로컬 및 STUN 사용) 및 TURN 서버와의 상호 작용. 각 참가자는 연결당 하나의 RTCMediaConnection을 가져야 합니다. 미디어 스트림은 암호화된 SRTP 프로토콜을 사용하여 전송됩니다.

턴 서버

ICE 후보에는 호스트, srflx 및 릴레이의 세 가지 유형이 있습니다. 호스트에는 로컬로 수신된 정보, srflx(노드가 외부 서버(STUN)에 어떻게 보이는지) 및 릴레이(TURN 서버를 통한 트래픽 프록시에 대한 정보)가 포함되어 있습니다. 노드가 NAT 뒤에 있는 경우 호스트 후보에는 다음이 포함됩니다. 현지 주소쓸모가 없을 것입니다. srflx 후보는 특정 유형의 NAT에만 도움이 될 것이며 릴레이는 중간 서버를 통해 트래픽을 전달하는 마지막 희망이 될 것입니다.

주소가 192.168.1.37이고 포트가 udp/34022인 호스트 유형의 ICE 후보의 예:

A=후보:337499441 2 udp 2113937151 192.168.1.37 34022 일반 호스트 세대 0

STUN/TURN 서버를 지정하기 위한 일반 형식:

Var 서버 = ( "iceServers": [ ( "url": "stun:stun.stunprotocol.org:3478" ), ( "url": "turn:user@host:port", "credential": "password" ) ]);

인터넷에는 공개 STUN 서버가 많이 있습니다. 예를 들어, 큰 목록이 있습니다. 불행하게도 그들은 너무 적은 문제를 해결합니다. STUN과 달리 공개 TURN 서버는 사실상 없습니다. 이는 TURN 서버가 미디어 스트림을 통과하여 네트워크 채널과 서버 자체를 모두 크게 로드할 수 있기 때문입니다. 따라서 TURN 서버에 연결하는 가장 쉬운 방법은 직접 설치하는 것입니다(물론 공용 IP가 필요합니다). 제 생각에는 모든 서버 중에서 가장 좋은 것은 rfc5766-turn-server입니다. Amazon EC2용으로 미리 만들어진 이미지도 있습니다.

TURN을 사용하면 모든 것이 원하는 만큼 좋지는 않지만 활발한 개발이 진행 중입니다. NAT(주소 변환) 및 방화벽을 통한 통과 품질 측면에서 WebRTC가 Skype와 동등하지는 않더라도 시간이 좀 지나면 좋겠습니다. , 적어도 눈에 띄게 가까워질 것입니다.

RTCMediaConnection은 연결을 설정하기 위해 제어 정보를 교환하기 위한 추가 메커니즘이 필요합니다. 비록 이 데이터를 생성하지만 전송하지는 않으며 다른 참가자에 대한 전송은 별도로 구현해야 합니다.


전송 방법의 선택은 적어도 수동으로 개발자에게 달려 있습니다. 필요한 데이터가 교환되는 즉시 RTCMediaConnection은 미디어 스트림을 자동으로 설치합니다(물론 가능하다면).

제안-응답 모델

미디어 스트림을 설정하고 변경하기 위해 제안/응답 모델(RFC3264에 설명됨)과 SDP(Session Description Protocol)가 사용됩니다. SIP 프로토콜에서도 사용됩니다. 이 모델에는 두 가지 에이전트가 있습니다. Offerer - 새 세션을 생성하거나 기존 세션을 수정하기 위해 세션에 대한 SDP 설명을 생성하는 사람(Offer SDP)과 Answerer - 세션에 대한 SDP 설명을 수신하는 사람 다른 에이전트가 자신의 세션 설명(Answer SDP)으로 응답합니다. 동시에 사양에는 에이전트 간 SDP 전송을 담당하는 더 높은 수준의 프로토콜(예: SIP 또는 우리의 경우 웹 소켓을 통한 자체 프로토콜)이 필요합니다.

미디어 스트림을 성공적으로 설정할 수 있도록 두 RTCMediaConnections 간에 어떤 데이터를 전달해야 합니까?

  • 연결을 시작하는 첫 번째 참가자는 전송을 시작하려는 미디어 스트림의 가능한 특성을 설명하는 SDP 데이터 구조(SIP에서 동일한 목적으로 동일한 프로토콜이 사용됨)를 전송하는 제안을 형성합니다. 이 데이터 블록은 두 번째 참가자에게 전송되어야 합니다. 두 번째 참가자는 SDP로 답변을 구성하여 첫 번째 참가자에게 보냅니다.
  • 첫 번째 참가자와 두 번째 참가자 모두 두 번째 참가자가 미디어 스트림을 전송할 수 있는 도움을 받아 가능한 ICE 후보를 결정하는 절차를 수행합니다. 후보자가 식별되면 해당 후보자에 대한 정보를 다른 참가자에게 전달해야 합니다.

형성 제안

제안을 생성하려면 두 가지 기능이 필요합니다. 성공적으로 형성되면 첫 번째 항목이 호출됩니다. createOffer() 메소드의 두 번째 매개변수는 실행 중 오류가 발생할 경우 호출되는 콜백 함수입니다(로컬 스레드가 이미 사용 가능한 경우).

또한 두 개의 이벤트 핸들러가 필요합니다. 새로운 ICE 후보를 정의할 때는 onicecandidate, 반대편에서 미디어 스트림을 연결할 때는 onaddstream이 필요합니다. 파일로 돌아가 보겠습니다. 요소가 있는 줄 뒤에 HTML에 또 하나를 추가해 보겠습니다.

제안 생성

그리고 해당 요소가 있는 줄 다음에(미래를 위해):


또한 JavaScript 코드 시작 부분에서 RTCPeerConnection에 대한 전역 변수를 선언합니다.

Var pc1;

RTCPeerConnection 생성자를 호출할 때 STUN/TURN 서버를 지정해야 합니다. 이에 대한 자세한 내용은 사이드바를 참조하세요. 모든 참가자가 동일한 네트워크에 있는 한 필요하지 않습니다.

Var 서버 = null;

제안 SDP 준비를 위한 매개변수

Var OfferConstraints = ();

createOffer() 메소드의 첫 번째 매개변수는 Offer가 성공적으로 형성될 때 호출되는 콜백 함수입니다.

Function pc1_createOffer_success(desc) ( console.log("pc1_createOffer_success(): \ndesc.sdp:\n"+desc.sdp+"desc:", desc); pc1.setLocalDescription(desc); // Offer SDP에서 생성된 RTCPeerConnection 설정 setLocalDescription 메소드를 사용하여 // 상대방이 Answer SDP를 보낼 때 setRemoteDescription 메소드를 사용하여 설정해야 합니다. // 두 번째 측면이 구현될 때까지 우리는 아무것도 하지 않습니다 // pc2_receivedOffer(desc); )

두 번째 매개변수는 오류 발생 시 호출되는 콜백 함수입니다.

함수 pc1_createOffer_error(error)( console.log("pc1_createOffer_success_error(): error:", error); )

그리고 ICE 후보가 결정되면 전달될 콜백 함수를 선언해 보겠습니다.

함수 pc1_onicecandidate(event)( if (event.candidate) ( console.log("pc1_onicecandidate():\n"+ event.candidate.candidate.replace("\r\n", ""), event.candidate); // 두 번째 측면이 구현될 때까지 아무것도 하지 않습니다. // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); ) )

또한 먼 쪽에서 미디어 스트림을 추가하기 위한 콜백 함수도 있습니다(현재로서는 RTCPeerConnection이 하나만 있기 때문에 미래를 위해).

함수 pc1_onaddstream(event) ( console.log("pc_onaddstream()"); remoteVideo1.src = URL.createObjectURL(event.stream); )

“createOffer” 버튼을 클릭하면 RTCPeerConnection을 생성하고 onicecandidate 및 onaddstream 메소드를 설정하며 createOffer() 메소드를 호출하여 Offer SDP 형성을 요청합니다.

Function createOffer_click() ( console.log("createOffer_click()"); pc1 = new webkitRTCPeerConnection(servers); // RTCPeerConnection 생성 pc1.onicecandidate = pc1_onicecandidate; // ICE 후보 처리를 위한 콜백 함수 pc1.onaddstream = pc1_onaddstream; // 먼 쪽에서 미디어 스트림이 나타날 때 호출되는 콜백 함수 아직 아무것도 없습니다. pc1.addStream(localStream); // 로컬 미디어 스트림을 전송하자(이미 수신했다고 가정) pc1.createOffer(// 실제로 요청합니다. 제안 pc1_createOffer_success , pc1_createOffer_error, OfferConstraints)의 형성; )

파일을 rtctest2.html로 저장하고, 서버에 업로드하고, 브라우저에서 열고, 작업 중에 어떤 데이터가 생성되는지 콘솔에서 확인해 보겠습니다. 참가자가 한 명뿐이므로 두 번째 영상은 아직 나타나지 않습니다. SDP는 미디어 세션의 매개변수에 대한 설명이며 사용 가능한 코덱, 미디어 스트림 및 ICE 후보는 특정 참가자에 연결하기 위한 가능한 옵션이라는 점을 기억해 보십시오.

Answer SDP 구성 및 ICE 후보자 교류

Offer SDP와 각 ICE 후보는 모두 상대방으로 전송되어야 하며, 이를 수신한 후 RTCPeerConnection은 Offer SDP에 대한 setRemoteDescription 메소드를 호출하고 반대편에서 수신된 각 ICE 후보에 대해 addIceCandidate를 호출합니다. 마찬가지로 반대쪽 Answer SDP 및 원격 ICE 후보자용입니다. Answer SDP 자체는 제안과 유사하게 구성됩니다. 차이점은 createOffer 메소드가 호출되는 것이 아니라 createAnswer 메소드가 호출되고 그 전에 RTCPeerConnection 메소드 setRemoteDescription이 호출자로부터 수신된 Offer SDP로 전달된다는 것입니다.

HTML에 다른 비디오 요소를 추가해 보겠습니다.

그리고 첫 번째 선언 아래 두 번째 RTCPeerConnection에 대한 전역 변수는 다음과 같습니다.

Var pc2;

제안 및 답변 처리 SDP

Answer SDP의 구성은 Offer와 매우 유사합니다. Offer와 유사하게 Answer가 성공적으로 형성되면 호출되는 콜백 함수에서 로컬 설명을 제공하고 수신된 Answer SDP를 첫 번째 참가자에게 전달합니다.

기능 pc2_createAnswer_success(desc) ( pc2.setLocalDescription(desc); console.log("pc2_createAnswer_success()", desc.sdp); pc1.setRemoteDescription(desc); )

Answer를 생성할 때 오류가 발생한 경우 호출되는 콜백 함수는 Offer와 완전히 유사합니다.

함수 pc2_createAnswer_error(error) ( console.log("pc2_createAnswer_error():", error); )

Answer SDP를 형성하기 위한 매개변수:

Var AnswerConstraints = ( "필수": ( "OfferToReceiveAudio":true, "OfferToReceiveVideo":true ) );

두 번째 참가자가 제안을 받으면 RTCPeerConnection을 생성하고 제안과 동일한 방식으로 답변을 구성합니다.

Function pc2_receivedOffer(desc) ( console.log("pc2_receiveOffer()", desc); // 첫 번째 참가자와 동일한 방법으로 두 번째 참가자에 대한 RTCPeerConnection 개체를 생성합니다. pc2 = new webkitRTCPeerConnection(servers); pc2.onicecandidate = pc2_onicecandidate ; // ICE가 나타날 때 이벤트 핸들러를 설정합니다. pc2.onaddstream = pc_onaddstream; // 스트림이 나타나면 HTML로 연결합니다. pc2.addStream(localStream); // 로컬 미디어 스트림을 전송합니다(이 예에서는 두 번째 스트림). 참가자는 첫 번째와 동일합니다.) // 이제 두 번째 RTCPeerConnection이 준비되면 수신된 Offer SDP를 전달합니다. (로컬 스트림을 첫 번째 스트림에 전달했습니다.) pc2.setRemoteDescription(new RTCSessionDescription(desc)); // 응답 메시지에 대한 데이터를 생성하기 위해 두 번째 연결을 요청합니다. pc2.createAnswer(pc2_createAnswer_success, pc2_createAnswer_error, AnswerConstraints); )

이 예에서는 Offer SDP를 첫 번째 참가자에서 두 번째 참가자로 전송하기 위해 pc1 함수에서 주석 처리를 제거하겠습니다. 제안 생성성공() 호출 라인:

Pc2_receivedOffer(desc);

ICE 후보 처리를 구현하려면 첫 번째 참가자 pc1_onicecandidate()의 ICE 후보 준비 이벤트 핸들러에서 두 번째 참가자로의 전송을 주석 해제해 보겠습니다.

Pc2.addIceCandidate(new RTCIceCandidate(event.candidate));

두 번째 참가자의 ICE 후보 준비 이벤트 핸들러는 첫 번째 참가자와 유사합니다.

함수 pc2_onicecandidate(event) ( if (event.candidate) ( console.log("pc2_onicecandidate():", event.candidate.candidate); pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); ) )

첫 번째 참가자의 미디어 스트림을 추가하기 위한 콜백 함수:

함수 pc2_onaddstream(event) ( console.log("pc_onaddstream()"); remoteVideo2.src = URL.createObjectURL(event.stream); )

연결 종료

HTML에 다른 버튼을 추가해 보겠습니다.

전화 끊기

그리고 연결을 종료하는 함수

함수 btnHangupClick() ( // HTML 요소에서 로컬 비디오 연결을 끊고 로컬 미디어 스트림을 중지하고 set = null localVideo1.src = ""; localStream.stop(); localStream = null; // 각 참가자에 대해 HTML에서 비디오를 비활성화합니다. 요소, 연결을 닫고 포인터를 설정합니다 = null remoteVideo1.src = ""; pc1.close(); pc1 = null; remoteVideo2.src = ""; pc2.close(); pc2 = null; )

rtctest3.html로 저장하고 서버에 업로드한 후 브라우저에서 열어보겠습니다. 이 예는 동일한 브라우저 탭 내의 두 RTCPeerConnections 간에 미디어 스트림의 양방향 전송을 구현합니다. 네트워크를 통해 참가자 간 Offer and Answer SDP, ICE 후보 및 기타 정보의 교환을 구성하려면 절차를 직접 호출하는 대신 일종의 전송(이 경우 웹 소켓)을 사용하여 참가자 간 교환을 구현해야 합니다.

스크린 방송

getUserMedia 함수는 다음 매개변수를 지정하여 화면을 캡처하고 MediaStream으로 스트리밍할 수도 있습니다.

Var mediaStreamConstraints = ( audio: false, video: ( 필수: ( chromeMediaSource: "screen"), 선택 사항: ) );

화면에 성공적으로 액세스하려면 다음과 같은 몇 가지 조건을 충족해야 합니다.

  • chrome://flags/,chrome://flags/의 getUserMedia()에서 스크린샷 플래그를 활성화합니다.
  • 소스 파일은 HTTPS(SSL 원본)를 통해 다운로드되어야 합니다.
  • 오디오 스트림을 요청하면 안 됩니다.
  • 하나의 브라우저 탭에서 여러 요청을 실행하면 안 됩니다.
WebRTC용 라이브러리

WebRTC는 아직 완성되지 않았지만 이를 기반으로 하는 여러 라이브러리가 이미 등장했습니다. JsSIP는 Asterisk 및 Camalio와 같은 SIP 스위치와 작동하는 브라우저 기반 소프트폰을 만들도록 설계되었습니다. PeerJS를 사용하면 데이터 교환을 위한 P2P 네트워크를 더 쉽게 만들 수 있으며 Holla는 브라우저에서 P2P 통신에 필요한 개발 양을 줄여줍니다.

Node.js와 소켓.io

네트워크를 통해 두 RTCPeerConnections 간의 SDP 및 ICE 후보 교환을 구성하기 위해 우리는 node.js와 node.js를 node.io 모듈과 함께 사용합니다.

최신 안정 버전의 Node.js(Debian/Ubuntu용) 설치에 대해 설명합니다.

$ sudo apt-get python-software-properties python g++ make $ sudo add-apt-repository ppa:chris-lea/node.js $ sudo apt-get update $ sudo apt-get install nodejs

다른 사람을 위한 설치 OS설명

점검 해보자:

$ echo "sys=require("util"); sys.puts("테스트 메시지");" > nodetest1.js $ nodejs nodetest1.js

npm(노드 패키지 관리자)을 사용하여 소켓.io 및 추가 Express 모듈을 설치합니다.

$ npm 설치 소켓.io 익스프레스

서버 측에 대한 nodetest2.js 파일을 생성하여 테스트해 보겠습니다.

$ nano nodetest2.js var app = require("express")() , server = require("http").createServer(app) , io = require("socket.io").listen(server); 서버.듣기(80); // 포트 80이 비어 있는 경우 app.get("/", function (req, res) ( // 루트 페이지에 액세스할 때 res.sendfile(__dirname + "/nodetest2.html"); // HTML 파일 전송 ) ) ; io.sockets.on("connection", function (socket) ( // 연결 시 소켓.emit("server event", ( hello: "world" )); // 메시지 전송 소켓.on("client event" , function (data) ( // 클라이언트에서 메시지가 도착할 때 이벤트 핸들러를 선언합니다. console.log(data); )); ));

그리고 클라이언트 측의 경우 nodetest2.html:

$ nano nodetest2.html var 소켓 = io.connect("/"); // 웹소켓 서버 URL(페이지가 로드된 서버의 루트 페이지) 소켓.on("서버 이벤트", function (data) ( console.log(data); 소켓.emit("클라이언트 이벤트", ( " 이름": "값" )); ));

서버를 시작해보자:

$ sudo nodejs nodetest2.js

브라우저에서 http://localhost:80(포트 80에서 로컬로 실행 중인 경우) 페이지를 엽니다. 모든 것이 성공하면 브라우저의 JavaScript 콘솔에서 연결 시 브라우저와 서버 간의 이벤트 교환을 볼 수 있습니다.

웹 소켓을 통한 RTCPeerConnection 간의 정보 교환 클라이언트 부분

주요 예제(rtcdemo3.html)를 새 이름 rtcdemo4.html로 저장해 보겠습니다. 요소에 소켓.io 라이브러리를 포함시켜 보겠습니다.

그리고 JavaScript 스크립트의 시작 부분에서 - 웹소켓에 연결합니다:

Var 소켓 = io.connect("http://localhost");

웹 소켓을 통해 메시지를 보내 다른 참가자의 기능에 대한 직접 호출을 대체해 보겠습니다.

함수 createOffer_success(desc) ( ... // pc2_receivedOffer(desc); 소켓.emit("offer", desc); ... ) 함수 pc2_createAnswer_success(desc) ( ... // pc1.setRemoteDescription(desc); 소켓 .emit("answer", desc); ) function pc1_onicecandidate(event) ( ... // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); 소켓.emit("ice1", event.candidate); .. . ) 함수 pc2_onicecandidate(event) ( ... // pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); 소켓.emit("ice2", event.candidate); ... )

hangup() 함수에서는 두 번째 참가자의 함수를 직접 호출하는 대신 웹 소켓을 통해 메시지를 전송합니다.

함수 btnHangupClick() ( ... // remoteVideo2.src = ""; pc2.close(); pc2 = null; 소켓.emit("hangup", ()); )

그리고 메시지 수신 핸들러를 추가합니다.

Socket.on("offer", function (data) ( console.log("socket.on("offer"):", data); pc2_receivedOffer(data); )); 소켓.on("답변", 함수 (데이터) (е console.log("socket.on("답변"):", data); pc1.setRemoteDescription(new RTCSessionDescription(data)); )); 소켓.on("ice1", function (data) ( console.log("socket.on("ice1"):", data); pc2.addIceCandidate(new RTCIceCandidate(data)); )); 소켓.on("ice2", function (data) ( console.log("socket.on("ice2"):", data); pc1.addIceCandidate(new RTCIceCandidate(data)); )); 소켓.on("hangup", 함수 (데이터) ( console.log("socket.on("hangup"):", data); remoteVideo2.src = ""; pc2.close(); pc2 = null; ) );

서버 부분

서버 측에서는 nodetest2 파일을 새 이름 rtctest4.js로 저장하고 io.sockets.on("connection", function (socket) ( ... ) 함수 내부에 클라이언트 메시지 수신 및 전송을 추가합니다.

Socket.on("offer", function (data) ( // "offer" 메시지를 받으면 // 이 예에서는 클라이언트 연결이 하나만 있으므로 // 동일한 소켓을 통해 메시지를 다시 보냅니다. .emit("offer" , data); // 발신자를 제외한 // 모든 연결을 통해 메시지를 전달해야 하는 경우: // soket.broadcast.emit("offer", data); )); 소켓.on("응답", 함수 (데이터) ( 소켓.emit("응답", 데이터); )); 소켓.on("ice1", function (data) (socket.emit("ice1", data); )); 소켓.on("ice2", function (data) ( 소켓.emit("ice2", data); )); 소켓.on("hangup", function (data) ( 소켓.emit("hangup", data); ));

또한 HTML 파일의 이름을 변경해 보겠습니다.

// res.sendfile(__dirname + "/nodetest2.html"); // HTML 파일 보내기 res.sendfile(__dirname + "/rtctest4.html");

서버 시작:

$ sudo nodejs nodetest2.js

두 클라이언트의 코드가 동일한 브라우저 탭 내에서 실행된다는 사실에도 불구하고 이 예에서 참가자 간의 모든 상호 작용은 완전히 네트워크를 통해 수행되며 참가자를 "분리"하는 데 특별한 어려움이 필요하지 않습니다. 그러나 우리가 한 일은 매우 간단했습니다. 이러한 기술은 사용하기 쉽기 때문에 좋습니다. 때로는 기만적일지라도. 특히 STUN/TURN 서버가 없으면 주소 변환 및 방화벽이 있는 경우 예제가 작동할 수 없다는 점을 잊지 마십시오.

결론

결과 예제는 매우 일반적이지만 호출자와 수신자 사이에 차이가 없도록 이벤트 핸들러를 약간 보편화하면 두 개체 pc1과 pc2 대신 RTCPeerConnection 배열을 만들고 구현합니다. 동적 생성요소를 제거하면 완전히 사용할 수 있는 영상 채팅이 가능해집니다. WebRTC와 관련된 특별한 세부 사항은 없으며 여러 참가자를 위한 간단한 영상 채팅의 예(기사에 있는 모든 예의 텍스트도 포함)는 잡지와 함께 제공되는 디스크에 있습니다. 그러나 이미 인터넷에서 꽤 많은 것을 찾을 수 있습니다. 좋은 예. 특히 기사를 준비하는 데 simpl.info getUserMedia, simpl.info RTCPeerConnection, WebRTC Reference App이 사용되었습니다.

곧 WebRTC 덕분에 음성 및 영상 통신에 대한 이해뿐만 아니라 인터넷 전체를 인식하는 방식에도 혁명이 일어날 것이라고 가정할 수 있습니다. WebRTC는 브라우저 간 호출 기술뿐만 아니라 실시간 통신 기술로도 자리잡고 있습니다. 우리가 논의한 영상통화는 극히 일부에 지나지 않습니다. 가능한 옵션그것의 사용. 스크린캐스팅과 협업의 예는 이미 있으며 RTCDataChannel을 사용하는 브라우저 기반 P2P 콘텐츠 전달 네트워크도 있습니다.




맨 위