Inizia a utilizzare WebRTC

WebRTC è un nuovo fronte nella lunga guerra per un web aperto e libero.

Brendan Eich, inventore di JavaScript

Comunicazione in tempo reale senza plug-in

Immagina un mondo in cui smartphone, TV e computer possono comunicare su una piattaforma comune. Immagina di poter aggiungere facilmente la chat video e la condivisione di dati peer-to-peer alla tua app web. Questa è la visione di WebRTC.

Vuoi provare? WebRTC è disponibile su computer e dispositivi mobili in Google Chrome, Safari, Firefox e Opera. Un buon punto di partenza è la semplice app di videochiamata disponibile all'indirizzo appr.tc:

  1. Apri appr.tc nel browser.
  2. Fai clic su Partecipa per entrare in una chat room e consentire all'app di utilizzare la webcam.
  3. Apri l'URL visualizzato alla fine della pagina in una nuova scheda o, meglio ancora, su un altro computer.

Avvio rapido

Non hai tempo di leggere questo articolo o vuoi solo il codice?

In alternativa, vai direttamente al codelab WebRTC, una guida passo passo che spiega come creare un'app di videochiamata completa, incluso un semplice server di segnalazione.

Una brevissima storia di WebRTC

Una delle ultime sfide principali per il web è consentire la comunicazione umana tramite voce e video: la comunicazione in tempo reale o RTC in breve. L'RTC dovrebbe essere naturale in un'app web come l'inserimento di testo in un input di testo. Senza, la tua capacità di innovare e sviluppare nuovi modi di interazione è limitata.

Storicamente, la comunicazione in tempo reale è stata aziendale e complessa, richiedendo la concessione di licenze o lo sviluppo interno di costose tecnologie audio e video. L'integrazione della tecnologia RTC con contenuti, dati e servizi esistenti è stata difficile e dispendiosa in termini di tempo, in particolare sul web.

La chat video di Gmail è diventata popolare nel 2008 e nel 2011 Google ha introdotto Hangouts, che utilizza Talk (come Gmail). Google ha acquistato GIPS, un'azienda che ha sviluppato molti componenti necessari per RTC, come codec e tecniche di cancellazione dell'eco. Google ha reso open source le tecnologie sviluppate da GIPS e ha collaborato con gli enti di standardizzazione pertinenti presso l'Internet Engineering Task Force (IETF) e il World Wide Web Consortium (W3C) per garantire il consenso del settore. Nel maggio 2011, Ericsson ha creato la prima implementazione di WebRTC.

WebRTC ha implementato standard aperti per la comunicazione in tempo reale di video, audio e dati senza plug-in. Il bisogno era reale:

  • Molti servizi web utilizzavano RTC, ma richiedevano download, app native o plug-in. Tra queste c'erano Skype, Facebook e Hangouts.
  • Il download, l'installazione e l'aggiornamento dei plug-in sono processi complessi, soggetti a errori e fastidiosi.
  • I plug-in sono difficili da implementare, sottoporre a debug, risolvere i problemi, testare e gestire e potrebbero richiedere licenze e integrazione con tecnologie complesse e costose. Spesso è difficile convincere le persone a installare i plug-in.

I principi guida del progetto WebRTC sono che le sue API devono essere open source, senza costi, standardizzate, integrate nei browser web e più efficienti delle tecnologie esistenti.

Dove ci troviamo ora?

WebRTC viene utilizzato in varie app, come Google Meet. WebRTC è stato integrato anche con WebKitGTK+ e le app native Qt.

WebRTC implementa queste tre API: - MediaStream (nota anche come getUserMedia) - RTCPeerConnection - RTCDataChannel

Le API sono definite in queste due specifiche:

Tutte e tre le API sono supportate su dispositivi mobili e computer da Chrome, Safari, Firefox, Edge e Opera.

getUserMedia: per demo e codice, vedi Esempi di WebRTC o prova gli esempi straordinari di Chris Wilson che utilizzano getUserMedia come input per l'audio web.

RTCPeerConnection: per una semplice demo e un'app di videochiamata completamente funzionante, consulta rispettivamente Esempi di connessione peer WebRTC e appr.tc. Questa app utilizza adapter.js, un shim JavaScript gestito da Google con l'aiuto della community WebRTC, per astrarre le differenze tra i browser e le modifiche alle specifiche.

RTCDataChannel: per vedere questa funzionalità in azione, consulta gli esempi di WebRTC per provare una delle demo del canale di dati.

Il codelab WebRTC mostra come utilizzare tutte e tre le API per creare una semplice app per la videochiamata e la condivisione di file.

Il tuo primo WebRTC

Le app WebRTC devono svolgere diverse operazioni:

  • Ricevere audio, video o altri dati in streaming.
  • Recupera le informazioni di rete, come indirizzi IP e porte, e scambiale con altri client WebRTC (noti come peer) per consentire la connessione, anche tramite NAT e firewall.
  • Coordina la comunicazione di segnalazione per segnalare errori e avviare o chiudere sessioni.
  • Scambia informazioni su media e funzionalità del client, come risoluzione e codec.
  • Comunicare audio, video o dati in streaming.

Per acquisire e comunicare i dati di streaming, WebRTC implementa le seguenti API:

  • MediaStream accede ai flussi di dati, ad esempio dalla videocamera e dal microfono dell'utente.
  • RTCPeerConnection consente chiamate audio o video con funzionalità di crittografia e gestione della larghezza di banda.
  • RTCDataChannel consente la comunicazione peer-to-peer di dati generici.

(In seguito verrà discussa in dettaglio la rete e gli aspetti di segnalazione di WebRTC).

API MediaStream (nota anche come API getUserMedia)

L'API MediaStream rappresenta flussi sincronizzati di contenuti multimediali. Ad esempio, uno stream acquisito dall'input della videocamera e del microfono ha tracce video e audio sincronizzate. Non confondere MediaStreamTrack con l'elemento <track>, che è qualcosa di completamente diverso.

Probabilmente il modo più semplice per comprendere l'API MediaStream è osservarla in azione:

  1. Nel browser, vai a Esempi WebRTC getUserMedia.
  2. Apri la console.
  3. Esamina la variabile stream, che si trova nell'ambito globale.

Ogni MediaStream ha un input, che potrebbe essere un MediaStream generato da getUserMedia(), e un output, che potrebbe essere passato a un elemento video o a un RTCPeerConnection.

Il metodo getUserMedia() accetta un parametro oggetto MediaStreamConstraints e restituisce un Promise che si risolve in un oggetto MediaStream.

Ogni MediaStream ha un label, ad esempio 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'. Un array di MediaStreamTrack viene restituito dai metodi getAudioTracks() e getVideoTracks().

Per l'esempio getUserMedia, stream.getAudioTracks() restituisce un array vuoto (perché non è presente audio) e, supponendo che sia collegata una webcam funzionante, stream.getVideoTracks() restituisce un array di un MediaStreamTrack che rappresenta lo stream della webcam. Ogni MediaStreamTrack ha un tipo ('video' o 'audio'), un label (ad esempio 'FaceTime HD Camera (Built-in)') e rappresenta uno o più canali audio o video. In questo caso, c'è una sola traccia video e nessun audio, ma è facile immaginare casi d'uso in cui ce ne sono di più, ad esempio un'app di chat che riceve stream dalla fotocamera anteriore, dalla fotocamera posteriore, dal microfono e un'app che condivide il suo schermo.

Un MediaStream può essere allegato a un elemento video impostando l'attributo srcObject. In precedenza, questa operazione veniva eseguita impostando l'attributo src su un URL oggetto creato con URL.createObjectURL(), ma questa operazione è stata ritirata.

getUserMedia può essere utilizzato anche come nodo di input per l'API Web Audio:

// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
  audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
  audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
  console.log('Sorry! Web Audio not supported.');
}

// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;

// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;

navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
  // Create an AudioNode from the stream.
  const mediaStreamSource =
    audioContext.createMediaStreamSource(stream);
  mediaStreamSource.connect(filterNode);
  filterNode.connect(gainNode);
  // Connect the gain node to the destination. For example, play the sound.
  gainNode.connect(audioContext.destination);
});

Le app e le estensioni basate su Chromium possono anche incorporare getUserMedia. L'aggiunta delle autorizzazioni audioCapture e/o videoCapture al manifest consente di richiedere e concedere l'autorizzazione una sola volta al momento dell'installazione. Dopodiché, all'utente non viene richiesta l'autorizzazione per l'accesso alla fotocamera o al microfono.

L'autorizzazione deve essere concessa una sola volta per getUserMedia(). La prima volta, nella barra delle informazioni del browser viene visualizzato un pulsante Consenti. L'accesso HTTP per getUserMedia() è stato ritirato da Chrome alla fine del 2015 perché classificato come funzionalità avanzata.

L'intenzione è potenzialmente quella di abilitare un MediaStream per qualsiasi origine dati di streaming, non solo una videocamera o un microfono. In questo modo, sarebbe possibile lo streaming da dati archiviati o da origini dati arbitrarie, come sensori o altri input.

getUserMedia() prende davvero vita in combinazione con altre API e librerie JavaScript:

  • Webcam Toy è un'app per fototessere che utilizza WebGL per aggiungere effetti strani e meravigliosi alle foto che possono essere condivise o salvate localmente.
  • FaceKat è un gioco di tracciamento facciale creato con headtrackr.js.
  • ASCII Camera utilizza l'API Canvas per generare immagini ASCII.
Immagine ASCII generata da idevelop.ro/ascii-camera
gUM ASCII art!

Vincoli

I vincoli possono essere utilizzati per impostare i valori della risoluzione video per getUserMedia(). Ciò consente anche il supporto di altri vincoli, come le proporzioni, la modalità di orientamento (fotocamera anteriore o posteriore), la frequenza fotogrammi, l'altezza e la larghezza, nonché un metodo applyConstraints().

Per un esempio, vedi Esempi di WebRTC getUserMedia: seleziona la risoluzione.

L'impostazione di un valore di vincolo non consentito restituisce un DOMException o un OverconstrainedError se, ad esempio, una risoluzione richiesta non è disponibile. Per vedere questa funzionalità in azione, consulta Esempi WebRTC getUserMedia: seleziona Risoluzione per una demo.

Acquisizione schermo e scheda

Le app Chrome consentono anche di condividere un video live di una singola scheda del browser o dell'intero desktop tramite le API chrome.tabCapture e chrome.desktopCapture. Per una demo e maggiori informazioni, vedi Condivisione dello schermo con WebRTC. L'articolo ha qualche anno, ma è ancora interessante.)

È anche possibile utilizzare l'acquisizione dello schermo come origine MediaStream in Chrome utilizzando il vincolo sperimentale chromeMediaSource. Tieni presente che l'acquisizione dello schermo richiede HTTPS e deve essere utilizzata solo per lo sviluppo, in quanto viene attivata tramite un flag della riga di comando, come spiegato in questo post.

Segnalazione: controllo della sessione, rete e informazioni sui contenuti multimediali

WebRTC utilizza RTCPeerConnection per comunicare i dati di streaming tra i browser (noti anche come peer), ma ha anche bisogno di un meccanismo per coordinare la comunicazione e inviare messaggi di controllo, un processo noto come segnalazione. I metodi e i protocolli di segnalazione non sono specificati da WebRTC. La segnalazione non fa parte dell'API RTCPeerConnection.

Gli sviluppatori di app WebRTC possono invece scegliere il protocollo di messaggistica che preferiscono, ad esempio SIP o XMPP, e qualsiasi canale di comunicazione bidirezionale appropriato. L'esempio appr.tc utilizza XHR e l'API Channel come meccanismo di segnalazione. Il codelab utilizza Socket.io in esecuzione su un server Node.

La segnalazione viene utilizzata per scambiare tre tipi di informazioni:

  • Messaggi di controllo della sessione: per inizializzare o chiudere la comunicazione e segnalare errori.
  • Configurazione di rete: per il mondo esterno, qual è l'indirizzo IP e la porta del tuo computer?
  • Funzionalità multimediali: quali codec e risoluzioni possono essere gestiti dal tuo browser e dal browser con cui vuole comunicare?

Lo scambio di informazioni tramite la segnalazione deve essere completato correttamente prima che possa iniziare lo streaming peer-to-peer.

Ad esempio, immagina che Alice voglia comunicare con Bob. Ecco un esempio di codice della specifica W3C WebRTC, che mostra il processo di segnalazione in azione. Il codice presuppone l'esistenza di un meccanismo di segnalazione creato nel metodo createSignalingChannel(). Tieni inoltre presente che su Chrome e Opera, RTCPeerConnection è attualmente preceduto da un prefisso.

// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);

// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});

// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
  try {
    await pc.setLocalDescription(await pc.createOffer());
    // Send the offer to the other peer.
    signaling.send({desc: pc.localDescription});
  } catch (err) {
    console.error(err);
  }
};

// Once remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
  // Don't set srcObject again if it is already set.
  if (remoteView.srcObject) return;
  remoteView.srcObject = event.streams[0];
};

// Call start() to initiate.
async function start() {
  try {
    // Get local stream, show it in self-view, and add it to be sent.
    const stream =
      await navigator.mediaDevices.getUserMedia(constraints);
    stream.getTracks().forEach((track) =>
      pc.addTrack(track, stream));
    selfView.srcObject = stream;
  } catch (err) {
    console.error(err);
  }
}

signaling.onmessage = async ({desc, candidate}) => {
  try {
    if (desc) {
      // If you get an offer, you need to reply with an answer.
      if (desc.type === 'offer') {
        await pc.setRemoteDescription(desc);
        const stream =
          await navigator.mediaDevices.getUserMedia(constraints);
        stream.getTracks().forEach((track) =>
          pc.addTrack(track, stream));
        await pc.setLocalDescription(await pc.createAnswer());
        signaling.send({desc: pc.localDescription});
      } else if (desc.type === 'answer') {
        await pc.setRemoteDescription(desc);
      } else {
        console.log('Unsupported SDP type.');
      }
    } else if (candidate) {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

Innanzitutto, Alice e Bob si scambiano informazioni sulla rete. L'espressione trovare candidati si riferisce al processo di ricerca di interfacce di rete e porte utilizzando il framework ICE.

  1. Alice crea un oggetto RTCPeerConnection con un gestore onicecandidate, che viene eseguito quando diventano disponibili i candidati di rete.
  2. Alice invia i dati serializzati dei candidati a Bob tramite il canale di segnalazione che sta utilizzando, ad esempio WebSocket o un altro meccanismo.
  3. Quando Bob riceve un messaggio candidato da Alice, chiama addIceCandidate per aggiungere il candidato alla descrizione del peer remoto.

I client WebRTC (noti anche come peer o Alice e Bob in questo esempio) devono anche determinare e scambiare informazioni sui contenuti multimediali audio e video locali e remoti, come la risoluzione e le funzionalità dei codec. La segnalazione per lo scambio di informazioni di configurazione dei contenuti multimediali avviene tramite lo scambio di un'offerta e di una risposta utilizzando il protocollo SDP (Session Description Protocol):

  1. Alice esegue il metodo RTCPeerConnection createOffer(). Il valore restituito viene passato a RTCSessionDescription, la descrizione della sessione locale di Alice.
  2. Nel callback, Alice imposta la descrizione locale utilizzando setLocalDescription() e poi invia questa descrizione della sessione a Bob tramite il canale di segnalazione. Tieni presente che RTCPeerConnection non inizierà a raccogliere candidati finché non viene chiamato setLocalDescription(). Questo è codificato nella bozza IETF JSEP.
  3. Bob imposta la descrizione che Alice gli ha inviato come descrizione remota utilizzando setRemoteDescription().
  4. Bob esegue il metodo RTCPeerConnection createAnswer(), trasmettendo la descrizione remota ricevuta da Alice in modo che possa essere generata una sessione locale compatibile con la sua. Il callback createAnswer() viene passato a un RTCSessionDescription. Bob la imposta come descrizione locale e la invia ad Alice.
  5. Quando Alice riceve la descrizione della sessione di Bob, la imposta come descrizione remota con setRemoteDescription.
  6. Ping.

RTCSessionDescription sono blob conformi al Session Description Protocol (SDP). Serializzato, un oggetto SDP ha questo aspetto:

v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126

// ...

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810

L'acquisizione e lo scambio di informazioni di rete e multimediali possono essere eseguiti contemporaneamente, ma entrambi i processi devono essere completati prima che possa iniziare lo streaming audio e video tra peer.

L'architettura offerta/risposta descritta in precedenza è chiamata JavaScript Session Establishment Protocol o JSEP. (Nel video dimostrativo di Ericsson per la sua prima implementazione di WebRTC è presente un'ottima animazione che spiega il processo di segnalazione e streaming.)

Diagramma dell&#39;architettura JSEP
Architettura JSEP

Una volta completata correttamente la procedura di segnalazione, i dati possono essere trasmessi in streaming direttamente peer-to-peer, tra il chiamante e il destinatario della chiamata oppure, in caso di errore, tramite un server di inoltro intermedio (maggiori dettagli in seguito). Lo streaming è compito di RTCPeerConnection.

RTCPeerConnection

RTCPeerConnection è il componente WebRTC che gestisce la comunicazione stabile ed efficiente dei dati di streaming tra i peer.

Di seguito è riportato un diagramma dell'architettura WebRTC che mostra il ruolo di RTCPeerConnection. Come noterai, le parti verdi sono complesse.

Diagramma dell&#39;architettura WebRTC
Architettura WebRTC (da webrtc.org)

Dal punto di vista di JavaScript, la cosa principale da capire di questo diagramma è che RTCPeerConnection protegge gli sviluppatori web dalla miriade di complessità che si nascondono sotto. I codec e i protocolli utilizzati da WebRTC fanno un enorme lavoro per rendere possibile la comunicazione in tempo reale, anche su reti inaffidabili:

  • Compensazione della perdita di pacchetti
  • Cancellazione dell'eco
  • Adattabilità della larghezza di banda
  • Jitter buffer dinamico
  • Controllo automatico guadagno
  • Riduzione ed eliminazione del rumore
  • Image-cleaning

Il codice W3C precedente mostra un esempio semplificato di WebRTC dal punto di vista della segnalazione. Di seguito sono riportate le procedure dettagliate di due app WebRTC funzionanti. Il primo è un semplice esempio per dimostrare RTCPeerConnection, mentre il secondo è un client di videochiamata completamente operativo.

RTCPeerConnection senza server

Il seguente codice è tratto da WebRTC samples Peer connection, che ha e RTCPeerConnection locali e remoti (e video locali e remoti) in una pagina web. Non si tratta di un'operazione molto utile, in quanto il chiamante e il chiamato si trovano sulla stessa pagina, ma rende il funzionamento dell'API RTCPeerConnection un po' più chiaro, perché gli oggetti RTCPeerConnection sulla pagina possono scambiarsi dati e messaggi direttamente senza dover utilizzare meccanismi di segnalazione intermedi.

In questo esempio, pc1 rappresenta il peer locale (chiamante) e pc2 rappresenta il peer remoto (chiamato).

Chiamante

  1. Crea un nuovo RTCPeerConnection e aggiungi lo stream da getUserMedia(): ```js // Servers is an optional configuration file. (Vedi la discussione su TURN e STUN più avanti.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
  1. Crea un'offerta e impostala come descrizione locale per pc1 e come descrizione remota per pc2. Questa operazione può essere eseguita direttamente nel codice senza utilizzare la segnalazione, perché sia il chiamante che il destinatario si trovano sulla stessa pagina: js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );

Callee

  1. Crea pc2 e, quando viene aggiunto lo stream da pc1, visualizzalo in un elemento video: js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }

RTCPeerConnection API e server

Nel mondo reale, WebRTC ha bisogno di server, anche se semplici, quindi può succedere quanto segue:

  • Gli utenti si scoprono a vicenda e si scambiano dettagli del mondo reale, come i nomi.
  • Le app client WebRTC (peer) scambiano informazioni di rete.
  • I peer si scambiano dati sui contenuti multimediali, come il formato e la risoluzione video.
  • Le app client WebRTC attraversano gateway NAT e firewall.

In altre parole, WebRTC ha bisogno di quattro tipi di funzionalità lato server:

  • Scoperta e comunicazione degli utenti
  • Segnalazioni
  • Attraversamento NAT/firewall
  • Server di inoltro in caso di comunicazione peer-to-peer non riuscita

Il NAT traversal, il networking peer-to-peer e i requisiti per la creazione di un'app server per la segnalazione e l'individuazione degli utenti non rientrano nell'ambito di questo articolo. Basti dire che il protocollo STUN e la sua estensione, TURN, vengono utilizzati dal framework ICE per consentire a RTCPeerConnection di gestire l'attraversamento NAT e altri imprevisti di rete.

ICE è un framework per connettere peer, ad esempio due client di chat video. Inizialmente, ICE tenta di connettere i peer direttamente con la latenza più bassa possibile tramite UDP. In questo processo, i server STUN hanno un unico compito: consentire a un peer dietro un NAT di scoprire il proprio indirizzo e la propria porta pubblici. Per ulteriori informazioni su STUN e TURN, consulta Crea i servizi di backend necessari per un'app WebRTC.

Trovare candidati per le connessioni
Trovare candidati per la connessione

Se UDP non funziona, ICE prova con TCP. Se la connessione diretta non riesce, in particolare a causa del NAT traversal e dei firewall aziendali, ICE utilizza un server TURN intermedio (relay). In altre parole, ICE utilizza prima STUN con UDP per connettere direttamente i peer e, in caso di errore, torna a un server di relay TURN. L'espressione trovare candidati si riferisce al processo di ricerca di interfacce di rete e porte.

Percorsi dei dati WebRTC
Percorsi dei dati WebRTC

L'ingegnere di WebRTC Justin Uberti fornisce ulteriori informazioni su ICE, STUN e TURN nella presentazione di Google I/O 2013 su WebRTC. Le slide della presentazione forniscono esempi di implementazioni dei server TURN e STUN.

Un semplice client di videochat

Un buon punto di partenza per provare WebRTC, con segnalazione e attraversamento NAT/firewall tramite un server STUN, è la demo di videochiamata all'indirizzo appr.tc. Questa app utilizza adapter.js, uno shim per isolare le app dalle modifiche alle specifiche e dalle differenze di prefisso.

Il codice è volutamente dettagliato nella registrazione. Controlla la console per capire l'ordine degli eventi. Di seguito è riportata una procedura dettagliata del codice.

Topologie di rete

WebRTC, nella sua attuale implementazione, supporta solo la comunicazione one-to-one, ma potrebbe essere utilizzato in scenari di rete più complessi, ad esempio con più peer che comunicano tra loro direttamente o tramite una Multipoint Control Unit (MCU), un server in grado di gestire un numero elevato di partecipanti ed eseguire l'inoltro selettivo di stream, nonché il mixaggio o la registrazione di audio e video.

Diagramma della topologia dell&#39;unità di controllo multipunto
Esempio di topologia di unità di controllo multipunto

Molte app WebRTC esistenti mostrano solo la comunicazione tra browser web, ma i server gateway possono consentire a un'app WebRTC in esecuzione su un browser di interagire con dispositivi come telefoni (noti anche come PSTN) e con sistemi VOIP. Nel maggio 2012, Doubango Telecom ha reso open source il client SIP sipml5 creato con WebRTC e WebSocket, che (tra gli altri potenziali utilizzi) consente le videochiamate tra browser e app in esecuzione su iOS e Android. In occasione di Google I/O, Tethr e Tropo hanno mostrato un framework per le comunicazioni in caso di disastri in una valigetta utilizzando una cella OpenBTS per consentire le comunicazioni tra feature phone e computer tramite WebRTC. Comunicazione telefonica senza operatore.

Demo di Tethr/Tropo al Google I/O 2012
Tethr/Tropo: Disaster communications in a briefcase

API RTCDataChannel<

Oltre ad audio e video, WebRTC supporta la comunicazione in tempo reale per altri tipi di dati.

L'API RTCDataChannel consente lo scambio peer-to-peer di dati arbitrari con bassa latenza e throughput elevato. Per demo di pagine singole e per scoprire come creare una semplice app di trasferimento di file, consulta rispettivamente Esempi WebRTC e il codelab WebRTC.

Esistono molti potenziali casi d'uso per l'API, tra cui:

  • Giochi
  • App di desktop remoto
  • Chat in tempo reale
  • Trasferimento file
  • Reti decentralizzate

L'API offre diverse funzionalità per sfruttare al meglio RTCPeerConnection e consentire una comunicazione peer-to-peer potente e flessibile:

  • Utilizzo della configurazione della sessione RTCPeerConnection
  • Più canali simultanei con assegnazione delle priorità
  • Semantica di distribuzione affidabile e non affidabile
  • Sicurezza integrata (DTLS) e controllo della congestione
  • Possibilità di utilizzare con o senza audio o video

La sintassi è volutamente simile a WebSocket, con un metodo send() e un evento message:

const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
  localConnection.createDataChannel('sendDataChannel');

// ...

remoteConnection.ondatachannel = (event) => {
  receiveChannel = event.channel;
  receiveChannel.onmessage = onReceiveMessage;
  receiveChannel.onopen = onReceiveChannelStateChange;
  receiveChannel.onclose = onReceiveChannelStateChange;
};

function onReceiveMessage(event) {
  document.querySelector("textarea#send").value = event.data;
}

document.querySelector("button#send").onclick = () => {
  var data = document.querySelector("textarea#send").value;
  sendChannel.send(data);
};

La comunicazione avviene direttamente tra i browser, quindi RTCDataChannel può essere molto più veloce di WebSocket anche se è necessario un server di inoltro (TURN) quando il hole punching per gestire firewall e NAT non va a buon fine.

RTCDataChannel è disponibile in Chrome, Safari, Firefox, Opera e Samsung Internet. Il gioco Cube Slam utilizza l'API per comunicare lo stato del gioco. Gioca con un amico o con l'orso. L'innovativa piattaforma Sharefest ha consentito la condivisione di file tramite RTCDataChannel e peerCDN ha offerto un'idea di come WebRTC potrebbe consentire la distribuzione di contenuti peer-to-peer.

Per ulteriori informazioni su RTCDataChannel, consulta la bozza delle specifiche del protocollo dell'IETF.

Sicurezza

Esistono diversi modi in cui un'app o un plug-in di comunicazione in tempo reale potrebbe compromettere la sicurezza. Ad esempio:

  • I contenuti multimediali o i dati non criptati potrebbero essere intercettati tra i browser o tra un browser e un server.
  • Un'app potrebbe registrare e distribuire video o audio senza che l'utente ne sia a conoscenza.
  • Malware o virus potrebbero essere installati insieme a un plug-in o un'app apparentemente innocui.

WebRTC offre diverse funzionalità per evitare questi problemi:

  • Le implementazioni WebRTC utilizzano protocolli sicuri, come DTLS e SRTP.
  • La crittografia è obbligatoria per tutti i componenti WebRTC, inclusi i meccanismi di segnalazione.
  • WebRTC non è un plug-in. I suoi componenti vengono eseguiti nella sandbox del browser e non in un processo separato. I componenti non richiedono un'installazione separata e vengono aggiornati ogni volta che viene aggiornato il browser.
  • L'accesso alla videocamera e al microfono deve essere concesso in modo esplicito e, quando la videocamera o il microfono sono in funzione, questo viene mostrato chiaramente dall'interfaccia utente.

Una discussione completa sulla sicurezza dei contenuti multimediali in streaming non rientra nell'ambito di questo articolo. Per maggiori informazioni, consulta la Proposed WebRTC Security Architecture proposta dall'IETF.

Conclusioni

Le API e gli standard di WebRTC possono democratizzare e decentralizzare gli strumenti per la creazione e la comunicazione di contenuti, tra cui telefonia, giochi, produzione video, creazione musicale e raccolta di notizie.

La tecnologia non può essere più dirompente di così.

Come ha scritto il blogger Phil Edholm: "Potenzialmente, WebRTC e HTML5 potrebbero consentire la stessa trasformazione per la comunicazione in tempo reale che il browser originale ha fatto per le informazioni".

Strumenti per sviluppatori

Scopri di più

Standard e protocolli

Riepilogo del supporto di WebRTC

API MediaStream e getUserMedia

  • Chrome per computer 18.0.1008 e versioni successive; Chrome per Android 29 e versioni successive
  • Opera 18 e versioni successive; Opera per Android 20 e versioni successive
  • Opera 12, Opera Mobile 12 (basato sul motore Presto)
  • Firefox 17 e versioni successive
  • Microsoft Edge 16 e versioni successive
  • Safari 11.2 e versioni successive su iOS e 11.1 e versioni successive su macOS
  • UC 11.8 e versioni successive su Android
  • Samsung Internet 4 e versioni successive

RTCPeerConnection API

  • Chrome desktop 20 e versioni successive; Chrome per Android 29 e versioni successive (senza flag)
  • Opera 18 e versioni successive (attivo per impostazione predefinita); Opera per Android 20 e versioni successive (attivo per impostazione predefinita)
  • Firefox 22 e versioni successive (attivato per impostazione predefinita)
  • Microsoft Edge 16 e versioni successive
  • Safari 11.2 e versioni successive su iOS e 11.1 e versioni successive su macOS
  • Samsung Internet 4 e versioni successive

RTCDataChannel API

  • Versione sperimentale in Chrome 25, ma più stabile (e con interoperabilità con Firefox) in Chrome 26 e versioni successive; Chrome per Android 29 e versioni successive
  • Versione stabile (e con interoperabilità di Firefox) in Opera 18 e versioni successive; Opera per Android 20 e versioni successive
  • Firefox 22 e versioni successive (attivato per impostazione predefinita)

Per informazioni più dettagliate sul supporto multipiattaforma per le API, come getUserMedia e RTCPeerConnection, consulta caniuse.com e Stato della piattaforma Chrome.

Le API native per RTCPeerConnection sono disponibili anche nella documentazione su webrtc.org.