Comienza a usar las conexiones entre pares

Las conexiones de intercambio de tráfico son la parte de las especificaciones de WebRTC que se encargan que conecta dos aplicaciones en computadoras diferentes para comunicarse con una protocolo entre pares. La comunicación entre pares puede ser de video, audio o datos binarios arbitrarios (para clientes que admiten la API de RTCDataChannel) En para descubrir cómo dos pares se pueden conectar, ambos clientes deben proporcionar una ICE Configuración del servidor. Este es un servidor STUN o TURN-server, y su rol es para proporcionar candidatos de ICE a cada cliente, el cual luego se transfiere al control remoto intercambio de tráfico. Esta transferencia de candidatos para ICE se suele denominar “indicación”.

Señalización

La especificación WebRTC incluye APIs para comunicarse con un ICE ( de la conectividad híbrida), pero el componente de señalización no forma parte del que la modifica. La señalización es necesaria para que dos pares compartan cómo deben conectarse. Por lo general, esto se resuelve a través de una API web basada en HTTP normal (es decir, una API de REST u otro mecanismo de RPC) donde las aplicaciones web pueden retransmitir antes de iniciar la conexión de intercambio de tráfico.

El siguiente fragmento de código muestra cómo se puede usar este servicio de señalización ficticia para envían y reciben mensajes de forma asíncrona. Se usará en el resto ejemplos en esta guía cuando sea necesario.

// 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 señalización se puede implementar de muchas maneras diferentes, y WebRTC esta especificación no prefiere ninguna solución específica.

Inicia conexiones con pares

Cada conexión de intercambio de tráfico es controlada por un objeto RTCPeerConnection. El constructor para esta clase toma un solo objeto RTCConfiguration como su parámetro. Esta define cómo se configura la conexión de intercambio de tráfico y debe contener información sobre los servidores ICE que se deben usar.

Una vez que se crea el RTCPeerConnection, debemos crear una oferta de SDP. dependiendo de si somos el par que realiza la llamada o el receptor. Una vez que el SDP se crea una oferta o respuesta, se debe enviar al par remoto a través de un en otro canal. Pasar objetos SDP a pares remotos se denomina señalización no está cubierta por la especificación WebRTC.

Para iniciar la configuración de la conexión de intercambio de tráfico desde el lado que realiza la llamada, creamos un RTCPeerConnection y, luego, llama a createOffer() para crear un Objeto RTCSessionDescription. La descripción de esta sesión se establece como con setLocalDescription() y, luego, se envía a través de nuestro de ese canal hacia el lado receptor. También configuramos un objeto de escucha para nuestra función de señalización canal para cuando se recibe una respuesta a la descripción de la sesión que ofrecemos el lado receptor.

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

En el lado receptor, esperamos una oferta entrante antes de crear nuestra Instancia RTCPeerConnection. Una vez hecho esto, configuramos la oferta recibida mediante setRemoteDescription() A continuación, llamamos a createAnswer() para crear una respuesta a la oferta recibida. Esta respuesta se establece como la descripción local con setLocalDescription() y, luego, se envía al lado que realiza la llamada a través de nuestra señal servidor.

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

Una vez que los dos compañeros han definido las descripciones de las sesiones locales y remotas, conocer las capacidades del par remoto. Esto no significa que la conexión entre pares está listo. Para que esto funcione, debemos recopilar la ICE candidatos en cada par y se transfieren (por el canal de señalización) a los otros intercambio de tráfico.

Candidatos de ICE

Antes de que dos pares puedan comunicarse usando WebRTC, deben intercambiar la información de conectividad. Debido a que las condiciones de la red pueden variar según de factores, se suele usar un servicio externo para descubrir posibles candidatos para conectarse con un compañero. Este servicio se llama ICE y es con un servidor STUN o TURN. STUN significa recorrido de sesión Utilidades para NAT y generalmente se usa de forma indirecta en la mayoría de las aplicaciones de WebRTC.

TURN (Recorrido con NAT de Relay) es la solución más avanzada que incorpora los protocolos STUN y la mayoría de los servicios comerciales basados en WebRTC usan un servidor TURN para establecer conexiones entre pares. La API de WebRTC admite STUN y TURN directamente, y se recopila bajo el término más completo Internet un establecimiento de conectividad. Al crear una conexión WebRTC, por lo general, proporcionar uno o varios servidores ICE en la configuración del RTCPeerConnection.

Goteo de hielo

Una vez que se crea un objeto RTCPeerConnection, el framework subyacente usa el proporcionaron servidores ICE para reunir a candidatos para el establecimiento de la conectividad (ICE) candidatos). El evento icegatheringstatechange en RTCPeerConnection indicadores en el estado de la recopilación ICE (new, gathering o complete).

Si bien es posible que un par espere hasta que se complete la recopilación de ICE, suele ser mucho más eficiente utilizar un "hielo goteo" técnica y transmitir cada candidato de ICE al par remoto a medida que se descubre. Si confirmas esta acción, reducir significativamente el tiempo de configuración para la conectividad entre pares y permitir que un video para comenzar con menos demoras.

Para recopilar candidatos de ICE, simplemente agrega un objeto de escucha para el evento icecandidate. El RTCPeerConnectionIceEvent emitido en ese objeto de escucha contendrá La propiedad candidate que representa un candidato nuevo que se debe enviar al intercambio de tráfico remoto (consulta Señalización).

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

Se estableció la conexión

Una vez que recibamos los candidatos del ICE, prevemos que conocerá el estado de nuestros pares. cada conexión cambiará a un estado conectado. Para detectar esto, agregamos un objeto de escucha a nuestro RTCPeerConnection, donde escuchamos connectionstatechange eventos.

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

API de RTCPeerConnection documentación