Was?
RTCQuicTransport ist eine neue Webplattform-API, die den Austausch beliebiger Daten mit Remote-Peers mithilfe des QUIC-Protokolls ermöglicht. Er ist für Peer-to-Peer-Anwendungsfälle vorgesehen und wird daher mit einer eigenständigen RTCIceTransport API verwendet, um eine Peer-to-Peer-Verbindung über ICE herzustellen. Die Daten werden zuverlässig und in der richtigen Reihenfolge übertragen. Weitere Informationen zur unsortierten und unzuverlässigen Zustellung finden Sie unten im Abschnitt. Da es sich um einen generischen, bidirektionalen Datentransport handelt, kann er für Spiele, Dateiübertragungen, Medientransport, Messaging usw. verwendet werden.
Woran liegt das?
Eine leistungsstarke Low-Level-Datenübertragungs-API kann Anwendungen (z. B. Echtzeitkommunikation) ermöglichen, neue Dinge im Web zu tun. Sie können auf der API aufbauen und eigene Lösungen erstellen, die die Grenzen der Möglichkeiten mit Peer-to-Peer-Verbindungen überschreiten, z. B. durch das Freischalten benutzerdefinierter Einstellungen für die Bitrate-Zuweisung. In Zukunft könnte eine weitere Unterstützung für codierte Medien sogar die Erstellung einer eigenen Videokommunikationsanwendung mit Low-Level-Steuerelementen ermöglichen. Das Ziel von WebRTC bei der NV-Forschung ist es, zu Low-Level-APIs zu wechseln. Frühzeitig damit zu experimentieren, ist sehr wertvoll.
Vorteile von QUIC
Für die Echtzeitkommunikation eignet sich das QUIC-Protokoll. Es basiert auf UDP, verfügt über eine integrierte Verschlüsselung, Überlastungskontrolle und Multiplexing ohne Head-of-Line-Blockierung. RTCQuicTransport
bietet sehr ähnliche Funktionen wie die RTCDataChannel
API, verwendet jedoch QUIC anstelle von SCTP als Transportprotokoll. Da es sich bei der RTCQuicTransport
um eine eigenständige API handelt, ist nicht der Aufwand der RTCPeerConnection
API erforderlich, die den Echtzeit-Medienstapel umfasst.
Wie geht das?
Allgemeine API-Übersicht
Die API hat drei Hauptabstraktionen: RTCIceTransport
, RTCQuicTransport
und RTCQuicStream
.
RTCIceTransport
ICE ist ein Protokoll zum Herstellen von Peer-to-Peer-Verbindungen über das Internet, das heute in WebRTC verwendet wird. Dieses Objekt stellt eine eigenständige API zum Herstellen einer ICE-Verbindung zur Verfügung. Es wird als Pakettransport für die QUIC-Verbindung verwendet und wird von RTCQuicTransport
in seinen Konstruktor übernommen.
RTCQuicTransport
Stellt eine QUIC-Verbindung dar. Damit wird eine QUIC-Verbindung hergestellt und QUIC-Streams erstellt. Außerdem werden relevante Statistiken für die QUIC-Verbindungsebene bereitgestellt.
RTCQuicStream
Wird zum Lesen und Schreiben von Daten auf/von der Remote-Seite verwendet. Streamt Transportdaten zuverlässig und in der richtigen Reihenfolge. Aus derselben RTCQuicTransport
können mehrere Streams erstellt werden. Sobald Daten in einen Stream geschrieben werden, wird ein „onquicstream“-Ereignis für den Remote-Transport ausgelöst. Streams bieten eine Möglichkeit, verschiedene Daten in derselben QUIC-Verbindung zu unterscheiden. Gängige Beispiele sind das Senden separater Dateien über separate Streams, kleine Datenblöcke über verschiedene Streams hinweg oder unterschiedliche Medientypen über separate Streams. RTCQuicStream
s sind unkompliziert, werden über eine QUIC-Verbindung ge Multiplext und verursachen keine Head-of-Line-Blockierung für andere RTCQuicStream
s.
Verbindungseinrichtung
Im Folgenden finden Sie ein Beispiel zum Einrichten einer Peer-to-Peer-QUIC-Verbindung.
Wie bei RTCPeerConnection
erfordert auch die RTCQuicTransport
API die Verwendung eines sicheren Signalisierungskanals, um die Parameter der Verbindung, einschließlich ihrer Sicherheitsparameter, auszuhandeln. Der RTCIceTransport
handelt seine ICE-Parameter (ufrag und Passwort) sowie die RTCIceCandidate
s aus.
Kundenperspektive:
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);
}
};
Serverperspektive:
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
Eine Datenübertragung kann mithilfe der RTCQuicStream APIs zum Lesen und Schreiben erreicht werden:
RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);
Zwischenspeichern
Die Promise, die von den waitFor*
-Methoden zurückgegeben werden, ermöglichen das Zwischenspeichern von Daten, wenn JavaScript ausgelastet ist. Wenn der Lesepuffer auf der Empfangsseite voll ist, wird auf die Sendeseite ein Gegendruck angewendet. Die Sendeseite hat einen Schreibpuffer, der gefüllt werden kann, wenn eine Gegenlast angewendet wird. Daher hat die Schreibseite auch eine waitForWriteBufferedAmountBelow
-Methode, um es zu ermöglichen, auf Platz im Zwischenspeicher zum Schreiben zu warten. Weitere Informationen zum Schreiben/Lesen von Daten finden Sie in der Entwicklerdokumentation.
Unbestellte/unzuverlässige Lieferung
Während ein RTCQuicStream
nur das zuverlässige und in der richtigen Reihenfolge ermöglicht, kann eine unzuverlässige/ungeordnete Übermittlung auf andere Weise erreicht werden. Bei einer ungeordneten Zustellung können kleine Datenblöcke in separaten Streams gesendet werden, da die Daten nicht zwischen den Streams sortiert sind. Bei unzuverlässigen Übermittlungen können kleine Datenblöcke gesendet werden, wobei der Abschluss auf „true“ gesetzt ist. Anschließend wird nach einer Zeitüberschreitung reset()
im Stream aufgerufen. Das Zeitlimit sollte davon abhängen, wie viele Weiterübertragungen gewünscht sind, bevor die Daten gelöscht werden.
Wann?
Der Ursprungstest beginnt in Chrome 73 und ist bis einschließlich M75 verfügbar. Danach endet der Ursprungstest. Je nach Feedback und Interesse werden wir entsprechende Änderungen vornehmen und die API entweder ausliefern, mit einem neuen Ursprungstest dieser API fortfahren oder die API einstellen.
Wo?
Chrome-Browser auf allen Plattformen außer iOS
Was noch?
Feedback
Eines der Hauptziele des Ursprungstests besteht darin, Feedback von Ihnen, den Entwicklern, zu erhalten. Wir interessieren uns für:
- Was ermöglicht Ihnen diese API?
- Welche Verbesserungen bietet diese API im Vergleich zu anderen Datenübertragungs-APIs (
WebSocket
s oderRTCDataChannel
von WebRTC) und was könnte sie noch verbessern? - Leistung
- Ergonomie der API
Für den Ursprungstest registrieren
- Fordern Sie ein Token für Ihren Ursprung an.
- Wenn Sie das Token Ihren Seiten hinzufügen, haben Sie zwei Möglichkeiten, es auf allen Seiten in Ihrem Ursprungsserver bereitzustellen:
- Fügen Sie im head-Abschnitt einer beliebigen Seite ein
origin-trial
<meta>
-Tag hinzu. Das kann beispielsweise so aussehen:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- Wenn du deinen Server konfigurieren kannst, hast du auch die Möglichkeit, das Token auf Seiten mit einem
Origin-Trial
-HTTP-Header bereitzustellen. Der resultierende Antwortheader sollte in etwa so aussehen:Origin-Trial: TOKEN_GOES_HERE
- Fügen Sie im head-Abschnitt einer beliebigen Seite ein
Web-Spezifikation
Die Entwurfsspezifikation wurde der API im Ursprungstest vorangebracht, einschließlich:
- Unidirektionale Streams, die eher an whatWG-Streams ausgerichtet sind
- Erneute Übertragungen deaktivieren
- Datagramme (demnächst verfügbar)
Wir möchten die vollständige Spezifikation und weitere Funktionen implementieren (einschließlich Unterstützung für WAGG-Streams), möchten aber zuerst dein Feedback hören.
Sicherheit
Die Sicherheit im QUIC-Handshake wird durch die Verwendung eines vorab freigegebenen Schlüssels erzwungen, um eine verschlüsselte P2P-QUIC-Verbindung herzustellen. Dieser Schlüssel muss über einen sicheren Out-of-Band-Kanal mit Vertraulichkeits- und Integritätsgarantien signalisiert werden. Der Schlüssel wird für JavaScript freigegeben.
Aktiver Angriff
Im Gegensatz zu DTLS-SRTP, das nur Integrität für die Signalisierung des Zertifikatsfingerabdrucks erfordert, erfordert die Signalisierung des vorab freigegebenen Schlüssels Integrität und Vertraulichkeit. Wenn der PSK manipuliert wird (z. B. durch den Server im Signalisierungskanal), könnte ein aktiver Angreifer potenziell einen Man-in-the-Middle-Angriff auf den QUIC-Handshake ausführen.
Aktueller Status
Step | Status |
---|---|
1. Erklärende Erklärung erstellen | Abschließen |
**2a. RTCQuicTransport-Spezifikation ** | **In Bearbeitung** |
**2b. RTCIceTransport-Spezifikation ** | **In Bearbeitung** |
**3. Feedback einholen und Design iterieren** | **In Bearbeitung** |
4. Ursprungstest | Ab Chrome 73! |
5. Einführung | Nicht gestartet |
Hilfreiche Links
- Weitere Dokumentation
- Öffentliche Erklärung
- Tracking-Fehler
- Ursprungstest-Token anfordern
- Ursprungstesttoken verwenden
- Diskussion zu Problemen mit RTCQuicTransport
- Diskussion zu Problemen mit RTCIceTransport