WebRTC - API de RTCPeerConnection

La API RTCPeerConnection es el núcleo de la conexión de igual a igual entre cada uno de los navegadores. Para crear los objetos RTCPeerConnection simplemente escriba

var pc = RTCPeerConnection(config);

donde el argumento de configuración contiene al menos una clave, iceServers. Es una serie de objetos URL que contienen información sobre los servidores STUN y TURN, utilizados durante la búsqueda de candidatos ICE. Puede encontrar una lista de servidores STUN públicos disponibles en code.google.com

Dependiendo de si usted es el llamador o el destinatario de la llamada, el objeto RTCPeerConnection se usa de una manera ligeramente diferente en cada lado de la conexión.

Aquí hay un ejemplo del flujo del usuario:

  • Registre el controlador onicecandidate . Envía los candidatos de ICE al otro par, a medida que los recibe.

  • Registre el controlador onaddstream . Maneja la visualización de la transmisión de video una vez que se recibe del par remoto.

  • Registre el controlador de mensajes . Su servidor de señalización también debe tener un controlador para los mensajes recibidos del otro par. Si el mensaje contiene el objeto RTCSessionDescription , debe agregarse al objeto RTCPeerConnection mediante el método setRemoteDescription () . Si el mensaje contiene el objeto RTCIceCandidate , debe agregarse al objeto RTCPeerConnection mediante el método addIceCandidate () .

  • Utilice getUserMedia () para configurar su flujo de medios local y agregarlo al objeto RTCPeerConnection usando el método addStream () .

  • Inicie el proceso de negociación de oferta / respuesta. Este es el único paso donde el flujo de la persona que llama es diferente al de la persona que llama. La persona que llama comienza la negociación utilizando el método createOffer () y registra una devolución de llamada que recibe el objeto RTCSessionDescription . A continuación, esta devolución de llamada debe agregar este RTCSessionDescription objeto a su RTCPeerConnection objeto utilizando setLocalDescription () . Y finalmente, la persona que llama debe enviar esta RTCSessionDescription al par remoto usando el servidor de señalización. El destinatario, por otro lado, registra la misma devolución de llamada, pero en el método createAnswer () . Observe que el flujo de llamadas se inicia solo después de que se recibe la oferta de la persona que llama.

API RTCPeerConnection

Propiedades

  • RTCPeerConnection.iceConnectionState (read only)- Devuelve una enumeración RTCIceConnectionState que describe el estado de la conexión. Se activa un evento iceconnectionstatechange cuando cambia este valor. Los posibles valores -

    • new - el agente de ICE está esperando candidatos remotos o reuniendo direcciones

    • checking - el agente de ICE tiene candidatos remotos, pero aún no ha encontrado una conexión

    • connected - el agente de ICE ha encontrado una conexión utilizable, pero aún está comprobando más candidatos remotos para una mejor conexión.

    • completed - el agente de ICE encontró una conexión utilizable y dejó de probar candidatos remotos.

    • failed - el agente de ICE ha verificado todos los candidatos remotos pero no encontró una coincidencia para al menos un componente.

    • disconnected - al menos un componente ya no está vivo.

    • closed - el agente de ICE está cerrado.

  • RTCPeerConnection.iceGatheringState (read only) - Devuelve una enumeración RTCIceGatheringState que describe el estado de recopilación de ICE para la conexión -

    • new - el objeto se acaba de crear.

    • gathering - el agente de ICE está en proceso de reunir candidatos

    • complete el agente de ICE ha terminado de reunirse.

  • RTCPeerConnection.localDescription (read only)- Devuelve una RTCSessionDescription que describe la sesión local. Puede ser nulo si aún no se ha establecido.

  • RTCPeerConnection.peerIdentity (read only)- Devuelve una RTCIdentityAssertion. Consiste en un idp (nombre de dominio) y un nombre que representa la identidad del par remoto.

  • RTCPeerConnection.remoteDescription (read only)- Devuelve una RTCSessionDescription que describe la sesión remota. Puede ser nulo si aún no se ha establecido.

  • RTCPeerConnection.signalingState (read only)- Devuelve una enumeración RTCSignalingState que describe el estado de señalización de la conexión local. Este estado describe la oferta de SDP. Se dispara un evento de señalización de cambio de estado cuando este valor cambia. Los posibles valores -

    • stable- El estado inicial. No hay ningún intercambio de oferta / respuesta SDP en curso.

    • have-local-offer - el lado local de la conexión ha aplicado localmente una oferta SDP.

    • have-remote-offer - el lado remoto de la conexión ha aplicado localmente una oferta SDP.

    • have-local-pranswer - Se aplicó una oferta de SDP remota y se aplicó localmente una respuesta de SDP.

    • have-remote-pranswer - Se aplicó un SDP local y se aplicó una respuesta de SDP de forma remota.

    • closed - la conexión está cerrada.

Controladores de eventos

S.No. Controladores de eventos y descripción
1

RTCPeerConnection.onaddstream

Este controlador se llama cuando se activa el evento addstream. Este evento se envía cuando el par remoto agrega un MediaStream a esta conexión.

2

RTCPeerConnection.ondatachannel

Este controlador se llama cuando se activa el evento de canal de datos. Este evento se envía cuando se agrega un RTCDataChannel a esta conexión.

3

RTCPeerConnection.onicecandidate

Este controlador se llama cuando se dispara el evento icecandidate. Este evento se envía cuando se agrega un objeto RTCIceCandidate al script.

4

RTCPeerConnection.oniceconnectionstatechange

Este controlador se llama cuando se activa el evento iceconnectionstatechange. Este evento se envía cuando cambia el valor de iceConnectionState.

5

RTCPeerConnection.onidentityresult

Este controlador se llama cuando se activa el evento de resultado de identidad. Este evento se envía cuando se genera una afirmación de identidad durante la creación de una oferta o una respuesta a través de getIdentityAssertion ().

6

RTCPeerConnection.onidpassertionerror

Este controlador se llama cuando se activa el evento idpassertionerror. Este evento se envía cuando el IdP (proveedor de identidad) encuentra un error al generar una afirmación de identidad.

7

RTCPeerConnection.onidpvalidation

Este controlador se llama cuando se activa el evento idpvalidationerror. Este evento se envía cuando el IdP (proveedor de identidad) encuentra un error al validar una afirmación de identidad.

8

RTCPeerConnection.onnegotiationneeded

Este controlador se llama cuando se activa el evento de negociación necesaria. Este evento es enviado por el navegador para informar que la negociación será necesaria en algún momento en el futuro.

9

RTCPeerConnection.onpeeridentity

Se llama a este controlador cuando se activa el evento de identidad de pares. Este evento se envía cuando se ha establecido y verificado una identidad de par en esta conexión.

10

RTCPeerConnection.onremovestream

Este controlador se llama cuando se dispara el evento signalingstatechange. Este evento se envía cuando cambia el valor de signalingState.

11

RTCPeerConnection.onsignalingstatechange

Se llama a este controlador cuando se activa el evento removestream. Este evento se envía cuando se elimina un MediaStream de esta conexión.

Métodos

S.No. Métodos y descripción
1

RTCPeerConnection()

Devuelve un nuevo objeto RTCPeerConnection.

2

RTCPeerConnection.createOffer()

Crea una oferta (solicitud) para encontrar un par remoto. Los dos primeros parámetros de este método son las devoluciones de llamada de éxito y error. El tercer parámetro opcional son opciones, como habilitar transmisiones de audio o video.

3

RTCPeerConnection.createAnswer()

Crea una respuesta a la oferta recibida por el par remoto durante el proceso de negociación de oferta / respuesta. Los dos primeros parámetros de este método son las devoluciones de llamada de éxito y error. El tercer parámetro opcional son opciones para que se cree la respuesta.

4

RTCPeerConnection.setLocalDescription()

Cambia la descripción de la conexión local. La descripción define las propiedades de la conexión. La conexión debe ser compatible con descripciones nuevas y antiguas. El método toma tres parámetros, objeto RTCSessionDescription, devolución de llamada si el cambio de descripción tiene éxito, devolución de llamada si falla el cambio de descripción.

5

RTCPeerConnection.setRemoteDescription()

Cambia la descripción de la conexión remota. La descripción define las propiedades de la conexión. La conexión debe ser compatible con descripciones nuevas y antiguas. El método toma tres parámetros, objeto RTCSessionDescription, devolución de llamada si el cambio de descripción tiene éxito, devolución de llamada si falla el cambio de descripción.

6

RTCPeerConnection.updateIce()

Actualiza el proceso del agente ICE de hacer ping a candidatos remotos y reunir candidatos locales.

7

RTCPeerConnection.addIceCandidate()

Proporciona un candidato remoto al agente de ICE.

8

RTCPeerConnection.getConfiguration()

Devuelve un objeto RTCConfiguration. Representa la configuración del objeto RTCPeerConnection.

9

RTCPeerConnection.getLocalStreams()

Devuelve una matriz de conexión MediaStream local.

10

RTCPeerConnection.getRemoteStreams()

Devuelve una matriz de conexión MediaStream remota.

11

RTCPeerConnection.getStreamById()

Devuelve MediaStream local o remoto por el ID proporcionado.

12

RTCPeerConnection.addStream()

Agrega un MediaStream como fuente local de video o audio.

13

RTCPeerConnection.removeStream()

Elimina un MediaStream como fuente local de video o audio.

14

RTCPeerConnection.close()

Cierra una conexión.

15

RTCPeerConnection.createDataChannel()

Crea un nuevo RTCDataChannel.

dieciséis

RTCPeerConnection.createDTMFSender()

Crea un nuevo RTCDTMFSender, asociado a un MediaStreamTrack específico. Permite enviar señalización telefónica DTMF (multifrecuencia de dos tonos) a través de la conexión.

17

RTCPeerConnection.getStats()

Crea un nuevo RTCStatsReport que contiene estadísticas sobre la conexión.

18

RTCPeerConnection.setIdentityProvider()

Establece el IdP. Toma tres parámetros: el nombre, el protocolo utilizado para comunicarse y un nombre de usuario opcional.

19

RTCPeerConnection.getIdentityAssertion()

Reúne una afirmación de identidad. No se espera tratar este método en la aplicación. Por lo tanto, puede llamarlo explícitamente solo para anticipar la necesidad.

Establecer una conexión

Ahora creemos una aplicación de ejemplo. En primer lugar, ejecute el servidor de señalización que creamos en el tutorial "servidor de señalización" a través de "servidor de nodo".

Habrá dos entradas de texto en la página, una para un inicio de sesión y otra para un nombre de usuario al que queremos conectarnos. Cree un archivo index.html y agregue el siguiente código:

<html lang = "en"> 
   <head> 
      <meta charset = "utf-8" /> 
   </head>
	
   <body> 
	
      <div> 
         <input type = "text" id = "loginInput" /> 
         <button id = "loginBtn">Login</button> 
      </div> 
	
      <div> 
         <input type = "text" id = "otherUsernameInput" />
         <button id = "connectToOtherUsernameBtn">Establish connection</button> 
      </div> 
		
      <script src = "client2.js"></script>
		
   </body>
	
</html>

Puede ver que hemos agregado la entrada de texto para un inicio de sesión, el botón de inicio de sesión, la entrada de texto para el nombre de usuario del otro compañero y el botón conectarse con él. Ahora cree un archivo client.js y agregue el siguiente código:

var connection = new WebSocket('ws://localhost:9090'); 
var name = ""; 
 
var loginInput = document.querySelector('#loginInput'); 
var loginBtn = document.querySelector('#loginBtn'); 
var otherUsernameInput = document.querySelector('#otherUsernameInput'); 
var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn'); 
var connectedUser, myConnection;
  
//when a user clicks the login button 
loginBtn.addEventListener("click", function(event){ 
   name = loginInput.value; 
	
   if(name.length > 0){ 
      send({ 
         type: "login", 
         name: name 
      }); 
   } 
	
});
  
//handle messages from the server 
connection.onmessage = function (message) { 
   console.log("Got message", message.data);
   var data = JSON.parse(message.data); 
	
   switch(data.type) { 
      case "login": 
         onLogin(data.success); 
         break; 
      case "offer": 
         onOffer(data.offer, data.name); 
         break; 
      case "answer": 
         onAnswer(data.answer); 
         break; 
      case "candidate": 
         onCandidate(data.candidate); 
         break; 
      default: 
         break; 
   } 
};
  
//when a user logs in 
function onLogin(success) { 

   if (success === false) { 
      alert("oops...try a different username"); 
   } else { 
      //creating our RTCPeerConnection object 
		
      var configuration = { 
         "iceServers": [{ "url": "stun:stun.1.google.com:19302" }] 
      }; 
		
      myConnection = new webkitRTCPeerConnection(configuration); 
      console.log("RTCPeerConnection object was created"); 
      console.log(myConnection); 
  
      //setup ice handling
      //when the browser finds an ice candidate we send it to another peer 
      myConnection.onicecandidate = function (event) { 
		
         if (event.candidate) { 
            send({ 
               type: "candidate", 
               candidate: event.candidate 
            }); 
         } 
      }; 
   } 
};
  
connection.onopen = function () { 
   console.log("Connected"); 
};
  
connection.onerror = function (err) { 
   console.log("Got error", err); 
};
  
// Alias for sending messages in JSON format 
function send(message) { 

   if (connectedUser) { 
      message.name = connectedUser; 
   } 
	
   connection.send(JSON.stringify(message)); 
};

Puede ver que establecemos una conexión de socket a nuestro servidor de señalización. Cuando un usuario hace clic en el botón de inicio de sesión, la aplicación envía su nombre de usuario al servidor. Si el inicio de sesión es exitoso, la aplicación crea el objeto RTCPeerConnection y configura un controlador de candidatos de hielo que envía todos los candidatos de hielo encontrados al otro par. Ahora abra la página e intente iniciar sesión. Debería ver la siguiente salida de la consola:

El siguiente paso es crear una oferta para el otro compañero. Agregue el siguiente código a su archivo client.js :

//setup a peer connection with another user 
connectToOtherUsernameBtn.addEventListener("click", function () { 
 
   var otherUsername = otherUsernameInput.value; 
   connectedUser = otherUsername;
	
   if (otherUsername.length > 0) { 
      //make an offer 
      myConnection.createOffer(function (offer) { 
         console.log(); 
         send({ 
            type: "offer", 
            offer: offer 
         });
			
         myConnection.setLocalDescription(offer); 
      }, function (error) { 
         alert("An error has occurred."); 
      }); 
   } 
}); 
 
//when somebody wants to call us 
function onOffer(offer, name) { 
   connectedUser = name; 
   myConnection.setRemoteDescription(new RTCSessionDescription(offer)); 
	
   myConnection.createAnswer(function (answer) { 
      myConnection.setLocalDescription(answer); 
		
      send({ 
         type: "answer", 
         answer: answer 
      }); 
		
   }, function (error) { 
      alert("oops...error"); 
   }); 
}
  
//when another user answers to our offer 
function onAnswer(answer) { 
   myConnection.setRemoteDescription(new RTCSessionDescription(answer)); 
} 
 
//when we got ice candidate from another user 
function onCandidate(candidate) { 
   myConnection.addIceCandidate(new RTCIceCandidate(candidate)); 
}

Puede ver que cuando un usuario hace clic en el botón "Establecer conexión", la aplicación hace una oferta de SDP al otro par. También configuramos los controladores onAnswer y onCandidate . Vuelva a cargar su página, ábrala en dos pestañas, inicie sesión con dos usuarios e intente establecer una conexión entre ellos. Debería ver la siguiente salida de la consola:

Ahora se establece la conexión peer-to-peer. En los próximos tutoriales, agregaremos transmisiones de video y audio, así como soporte de chat de texto.