Cosa?
RTCQuicTransport è una nuova API della piattaforma web che consente di scambiare dati arbitrari con peer remoti utilizzando il protocollo QUIC. È destinato ai 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 in ordine (vedi la sezione che segue per i dettagli sulla consegna non ordinata e non affidabile). Trattandosi di un trasporto di dati generico e bidirezionale, può essere utilizzato per giochi, trasferimenti di file, trasporto multimediale, messaggistica e così via.
Perché?
Una potente API di trasporto dati di basso livello può consentire alle applicazioni (come le comunicazioni in tempo reale) di fare nuove cose sul web. Puoi basarti sull'API, creando soluzioni personalizzate, spingendo i limiti di ciò che può essere fatto con connessioni peer to peer, ad esempio sbloccando manopole personalizzate di allocazione della velocità in bit. In futuro, un ulteriore supporto per i contenuti multimediali codificati potrebbe persino consentirti di creare la tua applicazione di comunicazione video con controlli di basso livello. L'impegno di NV di WebRTC è quello di passare alle API di livello inferiore e la sperimentazione anticipata di queste funzionalità è preziosa.
Perché QUIC?
Il protocollo QUIC è auspicabile per le comunicazioni in tempo reale. È basato su UDP, integra la crittografia e il controllo della congestione ed è multiplexato senza blocco dell'head of line. RTCQuicTransport
offre funzionalità molto simili
all'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 il media
stack in tempo reale.
Come?
Panoramica generale dell'API
L'API prevede 3 astrazioni principali: RTCIceTransport
, RTCQuicTransport
e RTCQuicStream
.
RTCIceTransport
ICE è un protocollo per stabilire connessioni peer-to-peer su Internet, attualmente utilizzato in WebRTC. Questo oggetto fornisce un'API autonoma per stabilire
una connessione ICE. Viene utilizzato come trasporto di pacchetti per la connessione QUIC e RTCQuicTransport
lo acquisisce nel suo costruttore.
RTCQuicTransport
Rappresenta una connessione QUIC. Viene utilizzato per stabilire una connessione QUIC e creare flussi QUIC. Mostra inoltre statistiche pertinenti per il livello di connessione QUIC.
RTCQuicStream
Utilizzato per la lettura e la scrittura di dati da/verso il lato remoto. I flussi trasportano i dati
in modo affidabile e in ordine. È possibile creare più flussi dallo stesso
RTCQuicTransport
e, una volta che i dati vengono scritti in un flusso, viene attivato un
evento "onquicstream" sul trasporto remoto. I flussi offrono un modo per distinguere dati diversi sulla stessa connessione QUIC. Esempi comuni possono essere l'invio di file separati in flussi separati, piccoli blocchi di dati in flussi diversi o diversi tipi di contenuti multimediali in flussi separati. Gli elementi RTCQuicStream
sono leggeri, sono multiplexati su una connessione QUIC e non causano blocco dell'head of line su altri RTCQuicStream
.
Configurazione della 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. RTCIceTransport
negozia i propri parametri ICE (ufrag e password) e RTCIceCandidate
.
Punto di vista 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);
}
};
Punto di vista 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);
}
};
Data Transfer
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 il buffering dei dati quando JavaScript è occupato. La contropressione viene applicata sul lato di invio quando il buffer di lettura si riempie sul lato di ricezione. Il lato di invio ha un buffer di scrittura che può riempire quando viene applicata la contropressione, pertanto anche il lato di scrittura ha un metodo waitForWriteBufferedAmountBelow
per consentire di attendere la scrittura nel buffer. Ulteriori informazioni sulla scrittura/lettura dei dati sono disponibili nell'ulteriore documentazione per gli sviluppatori.
Consegna non ordinata/non affidabile
Mentre un RTCQuicStream
supporta solo l'invio di dati in modo affidabile e in ordine,
una consegna non affidabile/non ordinata può essere ottenuta con altri mezzi. Per la consegna non ordinata, è possibile inviare piccoli blocchi di dati in flussi separati perché i dati non vengono ordinati tra i flussi. Per una consegna inaffidabile, è possibile inviare piccoli blocchi di dati con il valore di fine impostato su true, seguito dalla chiamata a reset()
nello stream dopo un timeout. Il timeout dovrebbe dipendere dal numero di ritrasmissioni desiderate prima di eliminare i dati.
Quando?
La prova dell'origine inizierà nella versione di Chrome 73 e sarà disponibile fino alla versione M75 inclusa. Dopodiché, la prova dell'origine terminerà. In base al feedback e all'interesse, apporteremo le modifiche necessarie e invieremo l'API, proseguiremo con una nuova prova dell'origine di questa API o interromperemo l'API.
Dove?
Browser Chrome in tutte le piattaforme tranne iOS.
Che altro?
Feedback
Uno degli obiettivi principali della prova dell'origine è ricevere un feedback da te, in quanto sviluppatori. Siamo interessati a:
- Che cosa ti consente di fare questa API?
- In che modo questa API migliora rispetto ad altre API di trasporto dei dati (
WebSocket
oRTCDataChannel
di WebRTC)? Come potrebbe migliorare? - Esibizione
- Ergonomia delle API
Registrati alla prova dell'origine
- Richiedi un token per la tua origine.
- Aggiungi il token alle tue pagine. Esistono due modi per fornire questo token su qualsiasi pagina della tua origine:
- Aggiungi un tag
<meta>
origin-trial
all'intestazione di qualsiasi pagina. Ad esempio, potrebbe essere simile al seguente:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- Se puoi configurare il server, puoi fornire il token anche sulle pagine utilizzando un'intestazione HTTP
Origin-Trial
. L'intestazione della risposta risultante dovrebbe essere simile al seguente:Origin-Trial: TOKEN_GOES_HERE
- Aggiungi un tag
Specifiche web
La bozza di specifica è stata avanzata rispetto all'API nella prova dell'origine, tra cui:
- Stream unidirezionali che sono più allineati con gli stream WHATWG
- Disattivazione delle ritrasmissioni
- Datagrammi (disponibili a breve)
Siamo interessati all'implementazione della specifica completa e non solo (compresa il supporto dello streaming WhatWG), ma vorremmo ricevere prima 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 segnalata tramite un canale out of band sicuro con garanzie di riservatezza e integrità. Tieni presente che la chiave sarà esposta a JavaScript.
Attacco attivo
A differenza di DTLS-SRTP, che richiede solo l'integrità per la segnalazione dell'impronta digitale del certificato, la segnalazione della chiave precondivisa richiede integrità e riservatezza. Se la PSK viene compromessa (ad esempio dal server nel canale di segnalazione), un utente malintenzionato attivo potrebbe attuare un attacco man in the middle contro l'handshake QUIC.
Stato attuale
Passaggio | Stato |
---|---|
1. Crea messaggio esplicativo | Completato |
**2a. Specifiche RTCQuicTransport ** | **In corso** |
**2b. Specifiche RTCIceTransport ** | **In corso** |
**3. Raccogli feedback e riformula il design** | **In corso** |
4. Prova dell'origine | Inizia in Chrome 73. |
5. Avvia | Not started |
Link utili
- Ulteriore documentazione
- Messaggio esplicativo pubblico
- Bug di monitoraggio
- Richiedere un token di prova dell'origine
- Come utilizzare un token della prova dell'origine
- Discussione sui problemi relativi a RTCQuicTransport
- Discussione sui problemi relativi a RTCIceTransport