Uruchamiamy wersję próbną RTCQuicTransport w pobliżu (Chrome 73)

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.

Schemat RTCQuicTransport przedstawiający architekturę interfejsu API

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.

Schemat RTCQuicTransport przedstawiający architekturę interfejsu API

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 (WebSockets lub WebRTC RTCDataChannel)? Jak można go ulepszyć?
  • Wyniki
  • Ergonomia interfejsu API

Rejestracja w wersji próbnej origin

  1. Poproś o token dla swojego źródła.
  2. 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

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