Quoi ?
RTCQuicTransport est une nouvelle API de plate-forme Web qui permet d'échanger des données arbitraires avec des pairs distants à l'aide du protocole QUIC. Il est destiné aux cas d'utilisation de pair à pair et est donc utilisé avec une API RTCIceTransport autonome pour établir une connexion de pair à pair via ICE. Les données sont transportées de manière fiable et dans l'ordre (voir la section ci-dessous pour en savoir plus sur la diffusion non ordonnée et non fiable). Comme il s'agit d'un transport de données bidirectionnel générique, il peut être utilisé pour les jeux, les transferts de fichiers, le transport multimédia, la messagerie, etc.
Pourquoi ?
Une API de transport de données de bas niveau puissante peut permettre aux applications (telles que les communications en temps réel) d'effectuer de nouvelles tâches sur le Web. Vous pouvez vous appuyer sur l'API pour créer vos propres solutions, repousser les limites de ce qui peut être fait avec les connexions point à point, par exemple, en débloquant les boutons d'allocation de débit personnalisés. À l'avenir, une meilleure prise en charge des médias encodés pourrait même vous permettre de créer votre propre application de communication vidéo avec des commandes de bas niveau. L'objectif de la NV de WebRTC est de passer à des API de niveau inférieur. Il est donc utile de commencer à tester cela dès le début.
Pourquoi QUIC ?
Le protocole QUIC est recommandé pour les communications en temps réel. Il est basé sur UDP, intègre le chiffrement et le contrôle de la congestion, et est multiplexé sans blocage de la tête de ligne. RTCQuicTransport
offre des fonctionnalités très similaires à celles de l'API RTCDataChannel
, mais utilise QUIC plutôt que SCTP comme protocole de transport. Étant donné que RTCQuicTransport
est une API autonome, elle ne présente pas les frais généraux de l'API RTCPeerConnection
, qui inclut la pile multimédia en temps réel.
Comment ?
Présentation générale de l'API
L'API comporte trois principales abstractions : RTCIceTransport
, RTCQuicTransport
et RTCQuicStream
.
RTCIceTransport
ICE est un protocole permettant d'établir des connexions peer-to-peer sur Internet. Il est utilisé dans WebRTC aujourd'hui. Cet objet fournit une API autonome pour établir une connexion ICE. Il est utilisé comme transport de paquets pour la connexion QUIC, et RTCQuicTransport
le prend dans son constructeur.
RTCQuicTransport
Représente une connexion QUIC. Il permet d'établir une connexion QUIC et de créer des flux QUIC. Il expose également des statistiques pertinentes pour le niveau de connexion QUIC.
RTCQuicStream
Permet de lire et d'écrire des données vers/à partir du côté distant. Les flux transportent les données de manière fiable et dans l'ordre. Vous pouvez créer plusieurs flux à partir du même RTCQuicTransport
. Une fois les données écrites dans un flux, un événement "onquicstream" est déclenché sur le transport à distance. Les flux permettent de distinguer différentes données sur la même connexion QUIC. Par exemple, vous pouvez envoyer des fichiers distincts sur des flux distincts, de petits blocs de données sur différents flux ou différents types de contenus multimédias sur des flux distincts. Les RTCQuicStream
sont légers, multiplexés sur une connexion QUIC et ne provoquent pas de blocage en tête de ligne pour d'autres RTCQuicStream
.
Configuration de la connexion
Vous trouverez ci-dessous un exemple de configuration d'une connexion QUIC point à point.
Comme RTCPeerConnection
, l'API RTCQuicTransport
nécessite l'utilisation d'un canal de signalisation sécurisé pour négocier les paramètres de la connexion, y compris ses paramètres de sécurité. RTCIceTransport
négocie ses paramètres ICE (ufrag et mot de passe), ainsi que les RTCIceCandidate
.
Point de vue du client:
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);
}
};
Point de vue du serveur:
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);
}
};
Transfert de données
Le transfert de données peut être effectué à l'aide des API RTCQuicStream pour la lecture et l'écriture:
RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);
Mise en mémoire tampon
Les promesses renvoyées par les méthodes waitFor*
permettent de mettre en mémoire tampon les données lorsque JavaScript est occupé. Une pression arrière est appliquée au côté d'envoi lorsque la mémoire tampon de lecture est pleine du côté de la réception. Le côté envoi dispose d'une mémoire tampon d'écriture qui peut se remplir lorsqu'une pression arrière a été appliquée. Par conséquent, le côté écriture dispose également d'une méthode waitForWriteBufferedAmountBelow
pour permettre d'attendre de l'espace dans la mémoire tampon pour écrire. Pour en savoir plus sur l'écriture/la lecture de données, consultez la documentation destinée aux développeurs.
Livraison non commandée/non fiable
Bien qu'un RTCQuicStream
n'accepte que l'envoi de données de manière fiable et dans l'ordre, la diffusion non fiable/non ordonnée peut être obtenue par d'autres moyens. Pour la diffusion non ordonnée, vous pouvez envoyer de petits blocs de données sur des flux distincts, car les données ne sont pas ordonnées entre les flux. Pour une diffusion non fiable, vous pouvez envoyer de petits blocs de données avec la valeur "true" pour "finish", puis appeler reset()
sur le flux après un délai avant expiration. Le délai avant expiration doit dépendre du nombre de nouvelles transmissions souhaitées avant de supprimer les données.
Quand ?
La phase de test de l'origine commencera avec la version 73 de Chrome et sera disponible jusqu'à la version M75, y compris. L'essai de l'origine prendra alors fin. En fonction des commentaires et de l'intérêt suscité, nous apporterons les modifications appropriées et déploierons l'API, poursuivrons une nouvelle phase d'évaluation de cette API ou abandonnerons l'API.
Où ces déclarations sont-elles formulées ?
Navigateur Chrome sur toutes les plates-formes, sauf iOS.
Quoi d'autre ?
Commentaires
L'un des principaux objectifs du test de l'origine est de recueillir vos commentaires, vous, les développeurs. Nous sommes intéressés par les éléments suivants:
- Que vous permet-elle ?
- En quoi cette API est-elle meilleure que les autres API de transport de données (
WebSocket
ouRTCDataChannel
de WebRTC) ? Comment pourrait-elle être améliorée ? - Performances
- Ergonomie des API
S'inscrire à l'essai de l'origine
- Demandez un jeton pour votre origine.
- Ajoutez le jeton à vos pages. Il existe deux façons de fournir ce jeton sur toutes les pages de votre origine :
- Ajoutez une balise
<meta>
origin-trial
dans l'en-tête de n'importe quelle page. Par exemple, cela peut se présenter comme suit :<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- Si vous pouvez configurer votre serveur, vous pouvez également fournir le jeton sur les pages à l'aide d'un en-tête HTTP
Origin-Trial
. L'en-tête de réponse obtenu doit se présenter comme suit:Origin-Trial: TOKEN_GOES_HERE
- Ajoutez une balise
Spécification Web
Le projet de spécification a pris le pas sur l'API dans le test d'origine, y compris:
- Flux unidirectionnels plus proches des flux WHATWG
- Désactiver les retransmissions
- (Bientôt disponible) datagrammes
Nous souhaitons implémenter la spécification complète et au-delà (y compris la prise en charge des flux WHATWG), mais nous aimerions d'abord connaître votre avis.
Sécurité
La sécurité dans l'échange QUIC est appliquée grâce à l'utilisation d'une clé pré-partagée pour établir une connexion QUIC P2P chiffrée. Cette clé doit être signalée via un canal hors bande sécurisé avec des garanties de confidentialité et d'intégrité. Notez que la clé sera exposée à JavaScript.
Attaque active
Contrairement à DTLS-SRTP, qui ne nécessite que l'intégrité pour signaler l'empreinte du certificat, la signalisation de la clé pré-partagée nécessite l'intégrité et la confidentialité. Si le PSK est compromis (par exemple, par le serveur dans le canal de signalisation), un pirate informatique actif peut potentiellement lancer une attaque de l'homme du milieu contre l'échange QUIC.
État actuel
Étape | État |
---|---|
1. Créer un message d'explication | Fin |
**2a. Spécification RTCQuicTransport ** | **En cours** |
**2b. Spécification RTCIceTransport ** | **En cours** |
**3. Recueillir des commentaires et itérer sur la conception** | **En cours** |
4. Essai Origin | Disponible à partir de Chrome 73 |
5. Lancer | Non démarrée |
Liens utiles
- Autres documents
- Explication publique
- Bug de suivi
- Demander un jeton d'essai d'origine
- Utiliser un jeton de test d'origine
- Discussion sur les problèmes liés à RTCQuicTransport
- Discussion sur les problèmes liés à RTCIceTransport