RTCQuicTransport in einem Ursprungstest in Ihrer Nähe (Chrome 73)

Was?

RTCQuicTransport ist eine neue Webplattform-API, mit der beliebige Daten mit Remote-Peers über das QUIC-Protokoll ausgetauscht werden können. Sie ist für Peer-to-Peer-Anwendungsfälle gedacht 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 ungeordneten und unzuverlässigen Zustellung finden Sie im Abschnitt unten. Da es sich um einen generischen, bidirektionalen Datentransport handelt, kann er für Gaming, Dateiübertragungen, Medientransport, Messaging usw. verwendet werden.

Warum?

Eine leistungsstarke Low-Level-Datentransport-API kann Anwendungen (z. B. Echtzeitkommunikation) neue Möglichkeiten im Web bieten. Du kannst die API als Grundlage für eigene Lösungen nutzen und die Möglichkeiten von Peer-to-Peer-Verbindungen erweitern, z. B. durch benutzerdefinierte Steuerelemente für die Bitrate. In Zukunft könnte eine weitere Unterstützung für codierte Medien sogar die Entwicklung einer eigenen Videokommunikationsanwendung mit Low-Level-Steuerelementen ermöglichen. Das Ziel der NV-Bemühungen von WebRTC ist es, zu APIs der unteren Ebene überzugehen. Frühzeitige Tests sind daher wertvoll.

Warum QUIC?

Das QUIC-Protokoll ist für die Echtzeitkommunikation geeignet. Es basiert auf UDP, verfügt über eine integrierte Verschlüsselung, Überlastungssteuerung und wird ohne Blockierung der Head-of-Line-Leitung multiplext. Die RTCQuicTransport bietet sehr ähnliche Funktionen wie die RTCDataChannel API, verwendet aber QUIC anstelle von SCTP als Transportprotokoll. Da die RTCQuicTransport eine eigenständige API ist, hat sie nicht den Overhead der RTCPeerConnection API, die den Echtzeit-Medienstack enthält.

Wie?

Allgemeine API-Übersicht

Die API hat drei Hauptabstraktionsebenen: RTCIceTransport, RTCQuicTransport und RTCQuicStream.

RTCQuicTransport-Diagramm mit der Architektur der API

RTCIceTransport

ICE ist ein Protokoll zum Herstellen von Peer-to-Peer-Verbindungen über das Internet und wird heute in WebRTC verwendet. Dieses Objekt bietet eine eigenständige API zum Herstellen einer ICE-Verbindung. Er wird als Pakettransport für die QUIC-Verbindung verwendet und von RTCQuicTransport in seinem Konstruktor übernommen.

RTCQuicTransport

Stellt eine QUIC-Verbindung dar. Er wird verwendet, um eine QUIC-Verbindung herzustellen und QUIC-Streams zu erstellen. Außerdem werden relevante Statistiken für die QUIC-Verbindungsebene angezeigt.

RTCQuicStream

Wird zum Lesen und Schreiben von Daten von/auf die Remoteseite verwendet. Streams übertragen Daten zuverlässig und in der richtigen Reihenfolge. Aus derselben RTCQuicTransport können mehrere Streams erstellt werden. Sobald Daten in einen Stream geschrieben wurden, wird ein „onquicstream“-Ereignis auf dem Remote-Transport ausgelöst. Streams bieten die Möglichkeit, verschiedene Daten über dieselbe QUIC-Verbindung zu unterscheiden. Gängige Beispiele sind das Senden separater Dateien über separate Streams, kleiner Datenmengen über verschiedene Streams oder verschiedener Medientypen über separate Streams. RTCQuicStreams sind effizient, werden über eine QUIC-Verbindung multiplext und verursachen keine Blockierung von anderen RTCQuicStreams.

Verbindungseinrichtung

Im Folgenden finden Sie ein Beispiel für die Einrichtung einer Peer-to-Peer-QUIC-Verbindung. Wie bei RTCPeerConnection ist für die RTCQuicTransport API die Verwendung eines sicheren Signalisierungskanals erforderlich, um die Parameter der Verbindung auszuhandeln, einschließlich der Sicherheitsparameter. Der RTCIceTransport verhandelt seine ICE-Parameter (ufrag und Passwort) sowie RTCIceCandidates.

RTCQuicTransport-Diagramm mit der Architektur der API

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);
  }
};

Datenübertragung

Die Datenübertragung kann mit den RTCQuicStream APIs für das Lesen und Schreiben erfolgen:

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

Pufferung

Die von den waitFor*-Methoden zurückgegebenen Promises ermöglichen das Puffern von Daten, wenn JavaScript beschäftigt ist. Ein Backpressure wird auf die Sendeseite angewendet, wenn der Lesepuffer auf der Empfangsseite voll ist. Die Sendeseite hat einen Schreibpuffer, der sich bei Gegendruck füllen kann. Daher hat die Schreibseite auch eine waitForWriteBufferedAmountBelow-Methode, mit der gewartet werden kann, bis im Puffer Platz zum Schreiben ist. Weitere Informationen zum Schreiben und Lesen von Daten finden Sie in der Entwicklerdokumentation.

Nicht bestellte/nicht zuverlässige Zustellung

Ein RTCQuicStream unterstützt zwar nur das zuverlässige und geordnete Senden von Daten, aber eine unzuverlässige/unsortierte Zustellung kann auch auf andere Weise erfolgen. Bei der unsortierten Bereitstellung können kleine Datenmengen in separaten Streams gesendet werden, da die Daten zwischen den Streams nicht sortiert werden. Bei einer unzuverlässigen Zustellung können kleine Datenblöcke mit „finish“ auf „true“ gesendet und nach einem Zeitlimit reset() auf den Stream aufgerufen werden. Die Zeitüberschreitung sollte davon abhängen, wie viele Wiederholungen gewünscht sind, bevor die Daten verworfen werden.

Wann?

Der Ursprungstest beginnt mit der Chrome-Version 73 und ist bis einschließlich der M75-Version verfügbar. Danach endet der Testzeitraum für die Quelle. Basierend auf dem Feedback und dem Interesse werden wir entsprechende Änderungen vornehmen und die API entweder veröffentlichen, mit einem neuen Test der 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 sind an folgenden Themen interessiert:

  • Was bietet diese API?
  • Inwiefern ist diese API im Vergleich zu anderen APIs für den Datentransport (WebSocket oder RTCDataChannel von WebRTC) besser? Wie könnte sie verbessert werden?
  • Leistung
  • API-Ergonomie

Für den Ursprungstest registrieren

  1. Fordere ein Token für deinen Ursprung an.
  2. Fügen Sie das Token Ihren Seiten hinzu. Es gibt zwei Möglichkeiten, dieses Token auf allen Seiten in Ihrem Ursprung bereitzustellen:
    • Fügen Sie dem Header einer beliebigen Seite das Tag origin-trial <meta> hinzu. Das könnte beispielsweise so aussehen: <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Wenn du deinen Server konfigurieren kannst, kannst du das Token auch auf Seiten mit einem Origin-Trial-HTTP-Header angeben. Der resultierende Antwortheader sollte in etwa so aussehen: Origin-Trial: TOKEN_GOES_HERE

Webspezifikation

Die Spezifikation ist im Ursprungstest weiter fortgeschritten als die API. Dazu gehören:

  • Einseitige Streams, die stärker an WHATWG-Streams ausgerichtet sind
  • Wiederholungen deaktivieren
  • (Demnächst) Datagramme

Wir möchten die vollständige Spezifikation und darüber hinaus (einschließlich WHATWG-Stream-Unterstützung) implementieren, möchten aber zuerst dein Feedback hören.

Sicherheit

Die Sicherheit beim QUIC-Handshake wird durch die Verwendung eines vorinstallierten 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 JavaScript zugänglich gemacht.

Aktiver Angriff

Im Gegensatz zu DTLS-SRTP, bei dem nur für die Signalisierung des Zertifikatsfingerabdrucks Integrität erforderlich ist, sind für die Signalisierung des freigegebenen Schlüssels Integrität und Vertraulichkeit erforderlich. Wenn das PSK manipuliert wird (z. B. vom Server im Signalisierungskanal), kann ein aktiver Angreifer möglicherweise einen Man-in-the-Middle-Angriff auf den QUIC-Handshake ausführen.

Aktueller Status

Schritt Status
1. Erläuternde Mitteilung erstellen Abschließen
**2a. RTCQuicTransport Specification ** **In Bearbeitung**
**2b. RTCIceTransport Specification ** **In Bearbeitung**
**3. Feedback einholen und Design iterieren** **In Bearbeitung**
4. Ursprungstest Ab Chrome 73
5. Starten Nicht gestartet

Hilfreiche Links