Wat?
De RTCQuicTransport is een nieuwe webplatform-API waarmee willekeurige gegevens kunnen worden uitgewisseld met externe collega's met behulp van het QUIC-protocol. Het is bedoeld voor peer-to-peer-gebruiksscenario's en wordt daarom gebruikt met een zelfstandige RTCIceTransport API om een peer-to-peer-verbinding tot stand te brengen via ICE . De gegevens worden betrouwbaar en in goede orde getransporteerd (zie onderstaande sectie voor details over ongeordende en onbetrouwbare levering). Omdat het een generiek, bidirectioneel datatransport is, kan het worden gebruikt voor gaming, bestandsoverdracht, mediatransport, berichtenuitwisseling, enz.
Waarom?
Een krachtige API voor datatransport op laag niveau kan applicaties (zoals realtime communicatie) in staat stellen nieuwe dingen op internet te doen. U kunt bovenop de API voortbouwen, uw eigen oplossingen creëren en de grenzen verleggen van wat mogelijk is met peer-to-peer-verbindingen, bijvoorbeeld door aangepaste knoppen voor bitrate-toewijzing te ontgrendelen. In de toekomst zou verdere ondersteuning voor gecodeerde media het zelfs mogelijk kunnen maken om uw eigen videocommunicatietoepassing te bouwen met bediening op laag niveau. De inspanningen van WebRTC NV zijn gericht op het ontwikkelen van API's op een lager niveau, en vroeg hiermee experimenteren is waardevol.
Waarom QUIC?
Het QUIC-protocol is wenselijk voor real-time communicatie. Het is gebouwd bovenop UDP, heeft ingebouwde encryptie, congestiecontrole en wordt gemultiplext zonder head-of-line-blokkering. De RTCQuicTransport
biedt zeer vergelijkbare mogelijkheden als de RTCDataChannel
API, maar gebruikt QUIC in plaats van SCTP als transportprotocol. Omdat de RTCQuicTransport
een zelfstandige API is, heeft deze niet de overhead van de RTCPeerConnection
API, die de realtime mediastack omvat.
Hoe?
Algemeen API-overzicht
De API heeft 3 hoofdabstracties, de RTCIceTransport
, RTCQuicTransport
en RTCQuicStream
.
RTCIceTransport
ICE is een protocol om peer-to-peer-verbindingen via internet tot stand te brengen en wordt tegenwoordig in WebRTC gebruikt. Dit object biedt een zelfstandige API om een ICE-verbinding tot stand te brengen. Het wordt gebruikt als pakkettransport voor de QUIC-verbinding, en RTCQuicTransport
neemt het op in zijn constructor.
RTCQuicTransport
Vertegenwoordigt een QUIC-verbinding. Het wordt gebruikt om een QUIC-verbinding tot stand te brengen en QUIC-streams te creëren. Het geeft ook relevante statistieken weer voor het QUIC-verbindingsniveau.
RTCQuicStream
Wordt gebruikt voor het lezen en schrijven van gegevens van/naar de externe kant. Streams transporteren gegevens betrouwbaar en geordend. Er kunnen meerdere streams worden gemaakt op basis van dezelfde RTCQuicTransport
en zodra gegevens naar een stream zijn geschreven, wordt er een 'onquicstream'-gebeurtenis op het externe transport geactiveerd. Streams bieden een manier om verschillende gegevens op dezelfde QUIC-verbinding van elkaar te onderscheiden. Veelvoorkomende voorbeelden zijn het verzenden van afzonderlijke bestanden over afzonderlijke stromen, kleine stukjes gegevens over verschillende stromen of verschillende soorten media over afzonderlijke stromen. RTCQuicStream
's zijn lichtgewicht, worden gemultiplext via een QUIC-verbinding en veroorzaken geen blokkering van de hoofdlijn naar andere RTCQuicStream
's.
Verbinding instellen
Het volgende is een voorbeeld voor het opzetten van een peer-to-peer QUIC-verbinding. Net als RTCPeerConnection
vereist de RTCQuicTransport
API het gebruik van een beveiligd signaleringskanaal om over de parameters van de verbinding te onderhandelen, inclusief de beveiligingsparameters. De RTCIceTransport
onderhandelt over de ICE-parameters (ufrag en wachtwoord), evenals over RTCIceCandidate
s.
Klantperspectief:
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);
}
};
Serverperspectief:
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);
}
};
Gegevensoverdracht
Gegevensoverdracht kan worden bereikt met behulp van de RTCQuicStream API's voor lezen en schrijven:
RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);
Bufferen
De beloften die door de waitFor*
-methoden worden geretourneerd, maken het mogelijk gegevens te bufferen wanneer JavaScript bezig is. Er wordt tegendruk uitgeoefend op de zendzijde wanneer de leesbuffer aan de ontvangstzijde vol raakt. De verzendzijde heeft een schrijfbuffer die kan worden gevuld als tegendruk is toegepast, en daarom heeft de schrijfzijde ook een waitForWriteBufferedAmountBelow
-methode om te wachten tot er ruimte in de buffer is om te schrijven. Meer informatie over het schrijven/lezen van gegevens vindt u in de verdere ontwikkelaarsdocumentatie .
Ongeordende/onbetrouwbare levering
Hoewel een RTCQuicStream
alleen het betrouwbaar en in volgorde verzenden van gegevens ondersteunt, kan een onbetrouwbare/ongeordende levering op andere manieren worden bereikt. Voor ongeordende levering kan men kleine stukjes gegevens over afzonderlijke stromen verzenden, omdat gegevens niet tussen stromen worden geordend. Voor onbetrouwbare levering kan men kleine stukjes gegevens verzenden met finish ingesteld op true, gevolgd door het aanroepen van reset()
op de stream na een time-out. De time-out moet afhankelijk zijn van het aantal hertransmissies dat gewenst is voordat de gegevens worden verwijderd.
Wanneer?
De origin-proefperiode start in de Chrome 73-versie en zal beschikbaar zijn tot en met de M75-versie. Hierna eindigt het oorsprongsproces. Op basis van feedback en interesse zullen we passende wijzigingen aanbrengen en de API verzenden, doorgaan met een nieuwe originele proefversie van deze API, of de API stopzetten.
Waar?
Chrome-browser op alle platforms behalve iOS.
Wat nog meer?
Feedback
Een van de belangrijkste doelen van de Origin-proef is om feedback van jullie, de ontwikkelaars, te krijgen. Wij zijn geïnteresseerd in:
- Wat maakt deze API voor u mogelijk?
- Hoe verbetert deze API andere API's voor gegevenstransport (
WebSocket
of WebRTC'sRTCDataChannel
)? Hoe zou het kunnen verbeteren? - Prestatie
- API-ergonomie
Meld u aan voor de origin-proefperiode
- Vraag een token aan voor uw herkomst.
- Voeg het token toe aan uw pagina's. Er zijn twee manieren om dit token op alle pagina's in uw oorsprong te plaatsen:
- Voeg een
origin-trial
<meta>
-tag toe aan de kop van elke pagina. Dit kan er bijvoorbeeld ongeveer zo uitzien:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- Als u uw server kunt configureren, kunt u het token ook op pagina's aanbieden met behulp van een
Origin-Trial
HTTP-header. De resulterende antwoordheader zou er ongeveer zo uit moeten zien:Origin-Trial: TOKEN_GOES_HERE
- Voeg een
Webspecificatie
De conceptspecificatie is in de origin-proef vooruitgegaan op de API, waaronder:
- Unidirectionele streams die nauwer aansluiten bij WHATWG-streams
- Hertransmissie uitschakelen
- (Binnenkort beschikbaar) datagrammen
We zijn geïnteresseerd in het implementeren van de volledige specificatie en meer (inclusief WHATWG-streamondersteuning), maar willen eerst uw feedback horen!
Beveiliging
De beveiliging van de QUIC-handshake wordt afgedwongen door het gebruik van een vooraf gedeelde sleutel om een gecodeerde P2P QUIC-verbinding tot stand te brengen. Deze sleutel moet worden gesignaleerd via een veilig out-of-band kanaal met vertrouwelijkheids- en integriteitsgaranties. Houd er rekening mee dat de sleutel wordt blootgesteld aan JavaScript.
Actieve aanval
In tegenstelling tot DTLS-SRTP, dat alleen integriteit vereist voor het signaleren van de certificaatvingerafdruk, vereist het signaleren van de vooraf gedeelde sleutel integriteit en vertrouwelijkheid. Als de PSK wordt aangetast (bijvoorbeeld door de server in het signaalkanaal), kan een actieve aanvaller mogelijk een man-in-the-middle-aanval uitvoeren tegen de QUIC-handshake.
Huidige status
Stap | Status |
---|---|
1. Maak een uitleg | Compleet |
**2a. RTCQuicTransport-specificatie ** | **In uitvoering** |
**2b. RTCIceTransport-specificatie ** | **In uitvoering** |
**3. Verzamel feedback en verbeter het ontwerp** | **In uitvoering** |
4. Oorsprongsproces | Start in Chrome 73! |
5. Lancering | Niet gestart |
Handige koppelingen
- Verdere documentatie
- Openbare uitlegger
- Tracking-bug
- Vraag een origin-proeftoken aan
- Een origin-proeftoken gebruiken
- Discussie over problemen voor RTCQuicTransport
- Discussie over problemen voor RTCIceTransport