RTCQuicTransport sta per iniziare una prova dell'origine vicino a te (Chrome 73)

Cosa?

RTCQuicTransport è una nuova API per piattaforme web che consente di scambiare dati arbitrari con peer remoti utilizzando il protocollo QUIC. È progettato per i casi d'uso peer-to-peer e, pertanto, viene utilizzato con un'API RTCIceTransport autonoma per stabilire una connessione peer-to-peer tramite ICE. I dati vengono trasportati in modo affidabile e ordinato (consulta la sezione di seguito per maggiori dettagli sulla pubblicazione non ordinata e non affidabile). Poiché si tratta di un trasporto di dati generico e bidirezionale, può essere utilizzato per giochi, trasferimenti di file, trasporto di contenuti multimediali, messaggistica e così via.

Perché?

Una potente API di trasporto dati a basso livello può consentire alle applicazioni (come le comunicazioni in tempo reale) di fare nuove cose sul web. Puoi creare soluzioni basate sull'API, creando le tue soluzioni, spingendo i limiti di ciò che è possibile fare con le connessioni peer-to-peer, ad esempio sbloccando i controlli di allocazione della velocità in bit personalizzata. In futuro, un ulteriore supporto per i contenuti multimediali codificati potrebbe persino consentire di creare la tua applicazione di comunicazione video con controlli a basso livello. L'obiettivo di WebRTC per la virtualizzazione di rete è passare ad API di livello inferiore e sperimentare in anteprima è molto importante.

Perché QUIC?

Il protocollo QUIC è preferibile per le comunicazioni in tempo reale. È basato su UDP, ha crittografia integrata, controllo della congestione ed è multiplexato senza blocco della priorità. RTCQuicTransport offre funzionalità molto simili a quelle dell'API RTCDataChannel, ma utilizza QUIC anziché SCTP come protocollo di trasporto. Poiché RTCQuicTransport è un'API autonoma, non ha il sovraccarico dell'API RTCPeerConnection, che include lo stack multimediale in tempo reale.

Come?

Panoramica generale dell'API

L'API ha tre astrazioni principali: RTCIceTransport, RTCQuicTransport e RTCQuicStream.

Diagramma di RTCQuicTransport che mostra l'architettura dell'API

RTCIceTransport

ICE è un protocollo per stabilire connessioni peer-to-peer su internet e viene attualmente utilizzato in WebRTC. Questo oggetto fornisce un'API autonoma per stabilire una connessione ICE. Viene utilizzato come trasporto dei pacchetti per la connessione QUIC e RTCQuicTransport lo prende nel suo costruttore.

RTCQuicTransport

Rappresenta una connessione QUIC. Viene utilizzato per stabilire una connessione QUIC e creare stream QUIC. Inoltre, espone le statistiche pertinenti per il livello di connessione QUIC.

RTCQuicStream

Utilizzato per leggere e scrivere dati verso/dal lato remoto. Gli stream trasportano i dati in modo affidabile e ordinato. È possibile creare più stream dallo stesso RTCQuicTransport e, una volta scritti i dati in uno stream, viene attivato un evento "onquicstream" sul trasporto remoto. Gli stream consentono di distinguere i dati diversi sulla stessa connessione QUIC. Alcuni esempi comuni possono essere l'invio di file separati su stream separati, piccoli blocchi di dati su stream diversi o diversi tipi di contenuti multimediali su stream separati. I RTCQuicStream sono leggeri, vengono multiplexati su una connessione QUIC e non causano il blocco della priorità per altri RTCQuicStream.

Configurazione connessione

Di seguito è riportato un esempio di configurazione di una connessione QUIC peer-to-peer. Come RTCPeerConnection, l'API RTCQuicTransport richiede l'utilizzo di un canale di segnalazione sicuro per negoziare i parametri della connessione, inclusi i relativi parametri di sicurezza. Il RTCIceTransport negozia i suoi parametri ICE (ufrag e password), nonché i RTCIceCandidate.

Diagramma di RTCQuicTransport che mostra l'architettura dell'API

Prospettiva del cliente:

const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
  iceParams: iceTransport.getLocalParameters(),
  quicKey: quicTransport.getKey(),
});
iceTransport.onicecandidate = e => {
  if (e.candidate) {
    signalingChannel.send({candidate: e.candidate});
  }
};

// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, candidate}) => {
  if (iceParams) {
    iceTransport.start(iceParams);
    quicTransport.connect();
  } else if (candidate) {
    iceTransport.addRemoteCandidate(candidate);
  }
};

Prospettiva del server:

const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
  iceParams: iceTransport.getLocalParameters(),
});
iceTransport.onicecandidate = e => {
  if (e.candidate) {
    signalingChannel.send({candidate: e.candidate});
  }
};

// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, quicKey, candidate}) => {
  if (iceParams && quicKey) {
    iceTransport.start(iceParams);
    quicTransport.listen(quicKey);
  } else if (candidate) {
    iceTransport.addRemoteCandidate(candidate);
  }
};

Trasferimento dei dati

Il trasferimento dei dati può essere eseguito utilizzando le API RTCQuicStream per la lettura e la scrittura:

RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);

Buffering

Le promesse restituite dai metodi waitFor* consentono di mettere in buffer i dati quando JavaScript è occupato. La contropressione viene applicata al lato di invio quando il buffer di lettura diventa pieno sul lato di ricezione. Il lato di invio ha un buffer di scrittura che può riempirsi quando viene applicata la contropressione e, pertanto, il lato di scrittura ha anche un metodo waitForWriteBufferedAmountBelow per consentire di attendere spazio nel buffer per la scrittura. Per ulteriori informazioni sulla scrittura/lettura dei dati, consulta la documentazione per gli sviluppatori.

Pubblicazione non ordinata/non affidabile

Sebbene un RTCQuicStream supporti solo l'invio di dati in modo affidabile e ordinato, la consegna non affidabile/non ordinata può essere ottenuta tramite altri mezzi. Per la carica non ordinata, è possibile inviare piccoli blocchi di dati su stream separati perché i dati non sono ordinati tra gli stream. Per l'invio non affidabile, è possibile inviare piccoli blocchi di dati con finish impostato su true, seguiti dalla chiamata di reset() sullo stream dopo un timeout. Il timeout deve dipendere dal numero di ritrasmissioni desiderate prima di eliminare i dati.

Quando?

La prova dell'origine inizierà nella versione 73 di Chrome e sarà disponibile fino alla versione M75 inclusa. Al termine, la prova dell'origine verrà chiusa. In base al feedback e all'interesse, apporteremo le modifiche necessarie e imposteremo l'API come disponibile, continueremo con una nuova prova dell'origine dell'API o la ritireremo.

Dove?

Browser Chrome su tutte le piattaforme tranne iOS.

Che altro?

Feedback

Uno degli obiettivi principali della prova dell'origine è ricevere feedback da voi, gli sviluppatori. Ci interessano:

  • Cosa ti consente questa API?
  • In che modo questa API è migliore rispetto ad altre API di trasporto dati (WebSocket o RTCDataChannel di WebRTC)? Come potrebbe essere migliorata?
  • Prestazioni
  • Ergonomia dell'API

Registrati per la prova dell'origine

  1. Richiedi un token per l'origine.
  2. Aggiungi il token alle tue pagine. Esistono due modi per fornire questo token su qualsiasi pagina dell'origine:
    • Aggiungi un tag origin-trial <meta> all'intestazione di qualsiasi pagina. Ad esempio, l'esempio potrebbe avere il seguente aspetto: <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Se puoi configurare il tuo server, puoi anche fornire il token nelle pagine utilizzando un'intestazione HTTP Origin-Trial. L'intestazione di risposta risultante dovrebbe avere il seguente aspetto: Origin-Trial: TOKEN_GOES_HERE

Specifiche web

La bozza della specifica è stata anticipata rispetto all'API nella prova di origine, tra cui:

  • Stream unidirezionali più in linea con gli stream WHATWG
  • Disattivare le ritrasmissioni
  • (Disponibile a breve) Datagrammi

Siamo interessati a implementare la specifica completa e non solo (incluso il supporto dello stream WHATWG), ma prima vogliamo conoscere il tuo feedback.

Sicurezza

La sicurezza nell'handshake QUIC viene applicata tramite l'utilizzo di una chiave precondivisa per stabilire una connessione QUIC P2P criptata. Questa chiave deve essere indicata su un canale out of band sicuro con garanzie di riservatezza e integrità. Tieni presente che la chiave verrà esposta a JavaScript.

Attacco attivo

A differenza di DTLS-SRTP, che richiede solo l'integrità per segnalare l'impronta del certificato, la segnalazione della chiave pre-condivisa richiede integrità e riservatezza. Se il PSK è compromesso (ad esempio dal server nel canale di segnalazione), un utente malintenzionato attivo potrebbe potenzialmente eseguire un attacco man-in-the-middle contro l'handshake QUIC.

Stato attuale

Step Stato
1. Creare un video esplicativo Completato
**2a. Specifiche RTCQuicTransport ** **In corso**
**2b. Specifiche RTCIceTransport ** **In corso**
**3. Raccogli feedback e esegui l'iterazione sul design** **In corso**
4. Prova dell'origine Inizia in Chrome 73.
5. Lancio Non avviato

Link utili