Guida introduttiva alle connessioni peer

Le connessioni peer fanno parte delle specifiche WebRTC che gestisce collegare due applicazioni su computer diversi per comunicare usando il protocollo peer-to-peer. La comunicazione tra app peer può essere video, audio o dati binari arbitrari (per i client che supportano l'API RTCDataChannel). Nella per scoprire come due colleghi possono connettersi, entrambi i clienti devono fornire un Configurazione del server. Si tratta di un server STUN o TURN e il suo ruolo di fornire candidati ICE a ciascun cliente, che viene poi trasferito al servizio remoto peer. Questo trasferimento di candidati ICE è comunemente chiamato segnalazione.

Segnalazione

La specifica WebRTC include API per comunicare con un ICE (Internet Connectivity Implementment), ma il componente di segnalazione non fa parte di li annotino. È necessaria la segnalazione per consentire a due colleghi di condividere come dovrebbero connettersi. Di solito questo problema si risolve tramite una normale API web basata su HTTP (ovvero un o un altro meccanismo RPC) in cui le applicazioni web possono inoltrare i le informazioni prima dell'inizio della connessione peer.

Lo snippet di codice "Segui" mostra come è possibile utilizzare questo servizio di segnalazione fittizio inviare e ricevere messaggi in modo asincrono. Verrà utilizzato nei restanti di esempio in questa guida, laddove necessario.

// 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!');

La segnalazione può essere implementata in molti modi diversi e il protocollo WebRTC specifica non preferisce una soluzione specifica.

Avvio delle connessioni peer

Ogni connessione peer è gestita da un oggetto RTCPeerConnection. Il costruttore per questa classe prende un singolo oggetto RTCConfiguration come parametro. Questo definisce la modalità di configurazione della connessione peer e deve contenere informazioni sui server ICE da utilizzare.

Una volta creato l'RTCPeerConnection, occorre creare un'offerta SDP. e la risposta corretta, a seconda che siamo il collega chiamante o il peer ricevente. Una volta che l'SSP un'offerta o una risposta, devono essere inviate al peer remoto tramite canale diverso. Il passaggio di oggetti SDP ai peer remoti è chiamato segnalazione e non è coperto dalla specifica WebRTC.

Per avviare la configurazione della connessione peer dal lato delle chiamate, creiamo una RTCPeerConnection, quindi chiama createOffer() per creare un RTCSessionDescription oggetto. La descrizione della sessione è impostata come descrizione locale descrizione utilizzando setLocalDescription() e viene poi inviata tramite la nostra segnalazione sul lato ricevente. Impostiamo anche un listener per le nostre canale per quando viene ricevuta una risposta alla descrizione della sessione che ti offriamo dal lato ricevente.

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});
}

Sul lato ricevente, attendiamo un'offerta in arrivo prima di creare RTCPeerConnection istanza. Dopodiché impostiamo l'offerta ricevuta utilizzando setRemoteDescription(). Quindi, chiamiamo createAnswer() per creare una risposta l'offerta ricevuta. Questa risposta è impostata come descrizione locale utilizzando setLocalDescription() e il messaggio verrà inviato al lato chiamante tramite la nostra segnalazione o server web.

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});
    }
});

Dopo aver impostato le descrizioni delle sessioni locali e remote, i due colleghi conoscere le capacità del peer remoto. Ciò non significa che la connessione tra le app peer è pronto. Affinché funzioni, dobbiamo raccogliere l'ICE candidati presso ciascun peer e trasferire (tramite il canale di segnalazione) all'altro peer.

candidati ICE

Prima che due colleghi possano comunicare utilizzando WebRTC, devono scambiarsi informazioni sulla connettività. Poiché le condizioni della rete possono variare in base di fattori, di solito un servizio esterno viene usato per scoprire possibili candidati per connettersi a un collega. Questo servizio si chiama ICE ed è utilizzando un server STUN o TURN. STUN è l'acronimo di Session Traversal Utility per NAT e di solito è utilizzato indirettamente nella maggior parte delle applicazioni WebRTC.

TURN (Traversal Using Relay NAT) è la soluzione più avanzata che incorpora i protocolli STUN e la maggior parte dei servizi commerciali basati su WebRTC utilizzano un server TURN per stabilire connessioni tra peer. L'API WebRTC supporta sia STUN e TURN direttamente e sono raggruppati con il termine più completo Istituzione della connettività. Quando creiamo una connessione WebRTC di solito fornire uno o più server ICE nella configurazione per RTCPeerConnection oggetto.

Ghiacciolo

Una volta creato un oggetto RTCPeerConnection, il framework sottostante utilizza la classe ha fornito server ICE per raccogliere i candidati per la connettività (ICE) candidati). Indicatori dell'evento icegatheringstatechange su RTCPeerConnection lo stato della raccolta dell'ICE (new, gathering o complete).

Sebbene sia possibile che un compagno attenda il completamento della raccolta dell'ICE, di solito è molto più efficiente nell'utilizzare il "ghiaccio artificiale" tecnica e trasmetteremo ogni candidato ICE al peer remoto non appena viene rilevato. In questo modo ridurre significativamente i tempi di configurazione della connettività peer e consentire per iniziare con meno ritardi.

Per raccogliere i candidati ICE, devi solo aggiungere un listener per l'evento icecandidate. Il valore RTCPeerConnectionIceEvent emesso in quel listener conterrà Proprietà candidate che rappresenta un nuovo candidato che deve essere inviato alla peer remoto (vedi Segnalazione).

// 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);
        }
    }
});

Connessione stabilita

Una volta ricevuti i candidati all'ICE, dovremmo aspettarci lo stato per i nostri colleghi la connessione passerà a uno stato connesso. Per rilevarlo, aggiungiamo un ascoltatore di RTCPeerConnection in cui ascoltiamo connectionstatechange eventi.

// Listen for connectionstatechange on the local RTCPeerConnection
peerConnection.addEventListener('connectionstatechange', event => {
    if (peerConnection.connectionState === 'connected') {
        // Peers connected!
    }
});

API RCPeerConnection documentazione