Co?
RTCQuicTransport to nowy interfejs API dla platformy internetowej, który umożliwia wymianę dowolnych danych z usługami na zdalnych komputerach za pomocą protokołu QUIC. Jest on przeznaczony do zastosowań typu peer-to-peer i dlatego jest używany z samodzielnym interfejsem RTCIceTransport API do nawiązywania połączeń peer-to-peer za pomocą ICE. Dane są przesyłane w sposób niezawodny i uporządkowany (szczegółowe informacje o nieuporządkowanej i niezawodnej dostawie znajdziesz w sekcji poniżej). Jest to ogólny, dwukierunkowy transport danych, który może być używany do gier, przesyłania plików, przesyłania multimediów, przesyłania wiadomości itp.
Dlaczego?
Potężny interfejs API do transportu danych na niskim poziomie może umożliwiać aplikacjom (np. komunikacji w czasie rzeczywistym) wykonywanie nowych zadań w internecie. Możesz tworzyć własne rozwiązania na podstawie interfejsu API, przesuwając granice tego, co można zrobić za pomocą połączeń typu peer-to-peer, na przykład odblokowując opcje niestandardowej alokacji szybkości transmisji. W przyszłości rozszerzona obsługa zakodowanych multimediów może umożliwić tworzenie własnych aplikacji do komunikacji wideo z możliwością sterowania na niskim poziomie. W ramach projektu WebRTC dotyczącego obrazu NV staramy się przejść na interfejsy API niższego poziomu. Warto już teraz eksperymentować z tą technologią.
Dlaczego QUIC?
Protokół QUIC jest zalecany do komunikacji w czasie rzeczywistym. Jest on oparty na protokole UDP, ma wbudowane szyfrowanie, kontrolę natężenia ruchu i jest multipleksowany bez blokowania priorytetów. Interfejs RTCQuicTransport
zapewnia bardzo podobne możliwości jak interfejs RTCDataChannel
API, ale jako protokół transportowy używa QUIC zamiast SCTP. Ponieważ interfejs RTCQuicTransport
jest samodzielnym interfejsem API, nie ma narzutu interfejsu API RTCPeerConnection
, który obejmuje pakiet mediów w czasie rzeczywistym.
Jak to zrobić?
Omówienie interfejsu API
Interfejs API ma 3 główne abstrakcje: RTCIceTransport
, RTCQuicTransport
i RTCQuicStream
.
RTCIceTransport
ICE to protokół służący do nawiązywania połączeń typu peer-to-peer przez Internet. Jest on obecnie używany w WebRTC. Ten obiekt udostępnia samodzielny interfejs API do nawiązywania połączenia ICE. Jest on używany jako transport pakietów dla połączenia QUIC, a RTCQuicTransport
przyjmuje go w swojej konstruktorze.
RTCQuicTransport
Reprezentuje połączenie QUIC. Służy do nawiązywania połączenia QUIC i tworzenia strumieni QUIC. Zawiera on też odpowiednie statystyki dotyczące poziomu połączenia QUIC.
RTCQuicStream
Służy do odczytu i zapisu danych na stronie zdalnej. Strumienie transportują dane w sposób niezawodny i uporządkowany. Z tego samego RTCQuicTransport
można utworzyć wiele strumieni, a gdy dane zostaną zapisane w strumieniu, uruchamiają zdarzenie „onquicstream” w usługach zdalnych. Strumienie umożliwiają rozróżnianie różnych danych w ramach tego samego połączenia QUIC. Typowymi przykładami są wysyłanie osobnych plików w ramach osobnych strumieni, przesyłanie małych fragmentów danych w ramach różnych strumieni lub przesyłanie różnych typów multimediów w ramach różnych strumieni. RTCQuicStream
są lekkie, multipleksowane przez połączenie QUIC i nie powodują blokowania innych RTCQuicStream
.
Konfiguracja połączenia
Poniżej znajdziesz przykład konfiguracji połączenia QUIC peer-to-peer.
Podobnie jak RTCPeerConnection
, interfejs API RTCQuicTransport
wymaga użycia bezpiecznego kanału sygnalizacji do negocjowania parametrów połączenia, w tym parametrów zabezpieczeń. RTCIceTransport
negocjuje parametry ICE (ufrag i hasło), a także RTCIceCandidate
.
Perspektywa klienta:
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);
}
};
Z punktu widzenia serwera:
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);
}
};
Przenoszenie danych
Przenoszenie danych można osiągnąć za pomocą interfejsów RTCQuicStream API do odczytu i zapisu:
RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);
Buforowanie
Obietnice zwracane przez metody waitFor*
umożliwiają buforowanie danych, gdy JavaScript jest zajęty. Ciśnienie wsteczne jest stosowane po stronie nadawania, gdy bufor odczytu zapełni się po stronie odbioru. Strona wysyłania ma bufor zapisu, który może się wypełnić, gdy zostanie zastosowana ciśnienie wsteczne. Dlatego strona zapisu ma też metodę waitForWriteBufferedAmountBelow
, która pozwala na oczekiwanie na miejsce w buforze na potrzeby zapisu. Więcej informacji o zapisywaniu i odczytywaniu danych znajdziesz w dokumentacji dla deweloperów.
Niezamówiona/niepewna dostawa
Podczas gdy RTCQuicStream
obsługuje tylko niezawodne i uporządkowane przesyłanie danych, niezawodne przesyłanie w nieuporządkowanej kolejności można uzyskać w inny sposób. W przypadku przesyłania niezporządkowanego można wysyłać małe fragmenty danych w osobnych strumieniach, ponieważ dane nie są uporządkowane między strumieniami. W przypadku niepewnej dostawy można wysyłać małe fragmenty danych z ustawioną wartością true w parametry finish, a potem wywołać reset()
w strumieniu po upływie limitu czasu. Czas oczekiwania powinien zależeć od tego, ile razy dane mają zostać przesłane, zanim zostaną odrzucone.
Kiedy?
Wersja próbna origin rozpocznie się w Chrome 73 i będzie dostępna do wersji M75 włącznie. Po tym okresie testowanie origin zostanie zakończone. Na podstawie opinii i zainteresowania wprowadzimy odpowiednie zmiany, a potem udostępnimy interfejs API, przeprowadzimy testy nowej wersji tego interfejsu API lub wycofamy go.
Gdzie?
przeglądarka Chrome na wszystkich platformach z wyjątkiem iOS;
Co jeszcze?
Prześlij opinię
Jednym z głównych celów okresu próbnego jest uzyskanie od Was, czyli programistów, opinii. Interesują nas:
- Co umożliwia ten interfejs API?
- Jak ten interfejs API jest lepszy od innych interfejsów API do transportu danych (
WebSocket
s lub WebRTCRTCDataChannel
)? Jak można go ulepszyć? - Wyniki
- Ergonomia interfejsu API
Rejestracja w wersji próbnej origin
- Poproś o token dla swojego źródła.
- Dodaj token do swoich stron. Możesz to zrobić na 2 sposoby:
- Dodaj tag
origin-trial
<meta>
do nagłówka dowolnej strony. Może to wyglądać na przykład tak:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- Jeśli masz możliwość skonfigurowania serwera, możesz też podać token na stronach za pomocą nagłówka HTTP
Origin-Trial
. Wynikowy nagłówek odpowiedzi powinien wyglądać mniej więcej tak:Origin-Trial: TOKEN_GOES_HERE
- Dodaj tag
Specyfikacja internetowa
W ramach testowania origin interfejsu API została udostępniona wersja robocza specyfikacji, która obejmuje:
- jednokierunkowe strumienie, które są bardziej zgodne ze strumieniami WHATWG;
- Wyłączanie retransmisji
- (wkrótce) datagramy
Chcemy wdrożyć pełną specyfikację (w tym obsługę strumieni WHATWG), ale najpierw chcemy poznać Twoją opinię.
Bezpieczeństwo
Bezpieczeństwo procedury ręcznego nawiązywania połączenia QUIC jest wymuszane przez użycie klucza wspólnego do ustanowienia szyfrowanego połączenia QUIC P2P. Ten klucz musi być sygnalizowany przez bezpieczny kanał poza pasmem, który zapewnia poufność i integralność. Pamiętaj, że klucz będzie dostępny dla JavaScriptu.
Aktywny atak
W odróżnieniu od DTLS-SRTP, które wymaga tylko integralności do sygnalizowania odcisku palca certyfikatu, sygnalizowanie udostępnionego wcześniej klucza wymaga integralności i poufności. Jeśli klucz PSK zostanie skompromitowany (np. przez serwer w kanale sygnalizacyjnym), aktywny atakujący może przeprowadzić atak typu „man-in-the-middle” na proces uzgadniania QUIC.
Obecny stan,
Krok | Stan |
---|---|
1. Tworzenie wyjaśnienia | Zakończono |
**2a. Specyfikacja RTCQuicTransport ** | **W toku** |
**2b. Specyfikacja RTCIceTransport ** | **W toku** |
**3. Zbieranie opinii i ulepszanie projektu** | **W toku** |
4. Wersja próbna origin | Zaczyna się w Chrome 73. |
5. Uruchom | Nie rozpoczęto |
Przydatne linki
- Dodatkowa dokumentacja
- Publiczny film wyjaśniający
- Śledzenie błędu
- Poproś o token okresu próbnego origin
- Jak używać tokenu wersji próbnej origin
- Dyskusja na temat problemów z RTCQuicTransport
- Dyskusja na temat problemów z RTCIceTransport