Połączenia równorzędne to część specyfikacji WebRTC, która obejmuje
łącząc dwie aplikacje na różnych komputerach w celu komunikacji
przez protokół peer-to-peer. Komunikacja między sobą może polegać na komunikacji wideo, audio lub
dowolne dane binarne (w przypadku klientów obsługujących interfejs API RTCDataChannel
). W
aby ustalić, w jaki sposób można nawiązać współpracę, obaj klienci muszą przedstawić ICE
Konfiguracja serwera. Jest to serwer STUN lub TURN, a jego rola to
przedstawianie kandydatów ICE każdemu klientowi, które są następnie przekazywane do zdalnego
w porównaniu z innymi wydawcami. Takie przekazywanie kandydatów z ICE jest powszechnie nazywane sygnalizowaniem.
Wysyłanie sygnałów
Specyfikacja WebRTC zawiera interfejsy API do komunikacji z ICE (internet) serwer połączenia), ale komponent sygnalizujący nie jest częścią . Sygnały są potrzebne, aby 2 równorzędne osoby mogły powiedzieć, jak powinny się połączyć. Zwykle do rozwiązania tego problemu używa się zwykłego internetowego interfejsu API opartego na protokole HTTP (np.REST). lub innym mechanizmem RPC), w którym aplikacje internetowe mogą przekazywać niezbędne informacje przed nawiązaniem połączenia z peerem.
Fragment kodu poniżej pokazuje, jak za pomocą tej fikcyjnej usługi sygnalizacji wysyłać i odbierać wiadomości w sposób asynchroniczny. Użyjemy go w pozostałej podanych w tym przewodniku.
// Set up an asynchronous communication channel that will be
// used during the peer connection setup
const signalingChannel = new SignalingChannel(remoteClientId);
signalingChannel.addEventListener('message', message => {
// New message from remote client received
});
// Send an asynchronous message to the remote client
signalingChannel.send('Hello!');
Sygnalizowanie można zaimplementować na wiele różnych sposobów, a WebRTC nie preferuje żadnego konkretnego rozwiązania.
Inicjowanie połączeń równorzędnych
Każde połączenie równorzędne jest obsługiwane przez obiekt RTCPeerConnection
. Konstruktor
dla tej klasy przyjmuje pojedynczy obiekt RTCConfiguration
jako parametr. Ten
obiekt określa sposób konfiguracji połączenia z peerem i powinien zawierać informacje
o serwerach ICE, które mają być używane.
Po utworzeniu RTCPeerConnection
musimy utworzyć ofertę SDP lub
w zależności od tego, czy dzwonimy do elementu równorzędnego, czy też go odbieramy. Gdy dostawca SDP
została utworzona oferta lub odpowiedź, musi zostać wysłana do zdalnego peera za pomocą
do innego kanału. Przekazywanie obiektów SDP do zdalnych połączeń jest nazywane sygnalizacją
nie jest ujęte w specyfikacji WebRTC.
Aby zainicjować konfigurację połączenia z peerem po stronie wywołującego, tworzymy
RTCPeerConnection
, a następnie wywołaj createOffer()
, by utworzyć
RTCSessionDescription
obiekt. Ten opis sesji jest ustawiony jako lokalny
opis za pomocą setLocalDescription()
, a następnie jest on przesyłany przez nasz sygnał
kanału w stronę odbiorcy. Skonfigurowaliśmy też nasłuchujący sygnały,
kanału, w którym odpowiedź na opis naszej sesji została otrzymana od
po stronie odbiorcy.
async function makeCall() {
const configuration = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]}
const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
if (message.answer) {
const remoteDesc = new RTCSessionDescription(message.answer);
await peerConnection.setRemoteDescription(remoteDesc);
}
});
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
signalingChannel.send({'offer': offer});
}
Czekamy na przychodzącą ofertę, zanim utworzymy
RTCPeerConnection
instancja. Następnie ustawiamy otrzymaną ofertę za pomocą
setRemoteDescription()
Następnie dzwonimy pod numer createAnswer()
, aby utworzyć odpowiedź
otrzymaną ofertę. Ta odpowiedź jest ustawiona jako opis lokalny za pomocą funkcji
setLocalDescription()
, a następnie został wysłany do rozmówcy przez nasz sygnalizowanie
serwera.
const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
if (message.offer) {
peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
signalingChannel.send({'answer': answer});
}
});
Gdy 2 koleżanki utworzą opis sesji lokalnej i zdalnej, poznaj możliwości zdalnego peera. Nie oznacza to, że połączenie jest gotowy. Aby to zadziałało, musimy zebrać dane ICE kandydatów z każdego z nich i przekazują (przez kanał sygnału) innym w porównaniu z innymi wydawcami.
Kandydaci ICE
Zanim 2 osoby będą mogły komunikować się za pomocą WebRTC, muszą wymienić się informacje o połączeniach. Ponieważ warunki sieci mogą się różnić w zależności od wielu czynników do wykrycia potencjalnych kandydatów do połączenia się z innymi. Jest to usługa ICE. przy użyciu serwera STUN lub TURN. STUN to skrót od Session Traversal Narzędzia dla NAT i zwykle są używane pośrednio w większości aplikacji WebRTC.
TURN (Traversal Using Relay NAT) to bardziej zaawansowane rozwiązanie, które obejmuje
protokoły STUN i większość komercyjnych usług opartych na WebRTC korzysta z serwera TURN
budowania relacji między rówieśnikami. Interfejs WebRTC API obsługuje zarówno protokół STUN,
i TURN, a dane te zbierane są pod
szybszym określeniem hasła Internet:
Nawiązywanie połączenia. Przy tworzeniu połączenia WebRTC
co najmniej jeden serwer ICE w konfiguracji
RTCPeerConnection
obiekt.
Krople ICE
Po utworzeniu obiektu RTCPeerConnection
podstawowa platforma używa metody
udostępnia serwery ICE w celu zbierania kandydatów do instytucji łączności (ICE)
). Zdarzenie icegatheringstatechange
w przypadku RTCPeerConnection
sygnałów
w jakim stanie jest zbiór danych ICE (new
, gathering
czy complete
).
Można by poczekać na zakończenie zbierania danych przez ICE, jest zwykle dużo bardziej skuteczny, jeśli używasz „kosmetyku lodowego”. technika i transmisja z każdym kandydatem ICE do zdalnego peera. Dzięki temu znacznie skrócić czas konfiguracji połączenia z innymi wydawcami i umożliwić przesyłanie filmów zadzwoń, by zacząć z mniejszym opóźnieniem.
Aby zebrać kandydatów ICE, po prostu dodaj detektor zdarzenia icecandidate
.
Pole RTCPeerConnectionIceEvent
emitowane przez ten detektor zawiera
candidate
reprezentującą nowego kandydata, który należy wysłać do
zdalny element równorzędny (patrz Sygnały).
// Listen for local ICE candidates on the local RTCPeerConnection
peerConnection.addEventListener('icecandidate', event => {
if (event.candidate) {
signalingChannel.send({'new-ice-candidate': event.candidate});
}
});
// Listen for remote ICE candidates and add them to the local RTCPeerConnection
signalingChannel.addEventListener('message', async message => {
if (message.iceCandidate) {
try {
await peerConnection.addIceCandidate(message.iceCandidate);
} catch (e) {
console.error('Error adding received ice candidate', e);
}
}
});
Połączenie zostało nawiązane
Po otrzymaniu kandydatów z ICE należy się spodziewać, że stan pozostałych kandydatów
stan połączenia zmieni się
w stan połączenia. Aby to wykryć, dodajemy parametr
słuchawka RTCPeerConnection
, w której słuchamy przez: connectionstatechange
zdarzeń.
// Listen for connectionstatechange on the local RTCPeerConnection
peerConnection.addEventListener('connectionstatechange', event => {
if (peerConnection.connectionState === 'connected') {
// Peers connected!
}
});