O quê?
O RTCQuicTransport é uma nova API de plataforma da Web que permite a troca de dados arbitrários com pares remotos usando o protocolo QUIC. Ele é destinado a casos de uso ponto a ponto e, portanto, é usado com uma API RTCIceTransport autônoma para estabelecer uma conexão ponto a ponto por meio do ICE. Os dados são transportados de maneira confiável e em ordem. Consulte a seção abaixo para detalhes sobre entregas não ordenadas e não confiáveis. Por ser um transporte de dados genérico e bidirecional, ele pode ser usado para jogos, transferências de arquivos, transporte de mídia, mensagens etc.
Por quê?
Uma API de transporte de dados de baixo nível pode permitir que aplicativos, como comunicações em tempo real, façam novas coisas na Web. Use a API como base, criando suas próprias soluções, ampliando os limites do que pode ser feito com conexões ponto a ponto, por exemplo, desbloqueando botões personalizados de alocação de taxa de bits. No futuro, mais suporte para mídia codificada poderá permitir a criação do seu próprio aplicativo de comunicação de vídeo com controles de baixo nível. O esforço de NV do WebRTC é mudar para APIs de nível inferior, e testar logo no início é valioso.
Por que o QUIC?
O protocolo QUIC é desejável para comunicações em tempo real. Ele é baseado
em UDP, tem criptografia integrada e controle de congestionamento, além de ser multiplexado sem
bloqueio de linha. O RTCQuicTransport
oferece recursos muito semelhantes aos
da API RTCDataChannel
, mas usa o QUIC em vez do SCTP como protocolo de
transporte. Como a RTCQuicTransport
é uma API independente, ela não tem
a sobrecarga da API RTCPeerConnection
, que inclui a pilha de mídia
em tempo real.
Como?
Visão geral da API
A API tem três abstrações principais: RTCIceTransport
, RTCQuicTransport
e RTCQuicStream
.
RTCIceTransport
O ICE é um protocolo para estabelecer conexões ponto a ponto pela Internet e
é usado atualmente no WebRTC. Esse objeto fornece uma API autônoma para estabelecer
uma conexão ICE. Ele é usado como o transporte de pacote para a conexão QUIC,
e o RTCQuicTransport
o recebe no construtor.
RTCQuicTransport
Representa uma conexão QUIC. Ele é usado para estabelecer uma conexão QUIC e criar streams QUIC. Ele também expõe estatísticas relevantes para o nível de conexão do QUIC.
RTCQuicStream
Usado para ler e gravar dados no lado remoto. Os streams transportam
dados de maneira confiável e em ordem. É possível criar vários streams a partir do mesmo
RTCQuicTransport
. Depois que os dados são gravados em um stream, eles disparam um
evento "onquicstream" no transporte remoto. Os streams são uma maneira de
distinguir dados diferentes na mesma conexão QUIC. Exemplos comuns podem
ser o envio de arquivos separados em streams separados, pequenos blocos de dados em
diferentes streams ou diferentes tipos de mídia em streams separados.
RTCQuicStream
s são leves, multiplexados em uma conexão QUIC e
não causam bloqueio de cabeça de linha para outros RTCQuicStream
s.
Configuração da conexão
Veja a seguir um exemplo de configuração de uma conexão QUIC ponto a ponto.
Como RTCPeerConnection
, a API RTCQuicTransport
requer o uso de um
canal de sinalização seguro para negociar os parâmetros da conexão,
incluindo os parâmetros de segurança. O RTCIceTransport
negocia os parâmetros ICE (ufrag e senha), além dos RTCIceCandidate
s.
Perspectiva do cliente:
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);
}
};
Perspectiva do servidor:
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);
}
};
Transferência de dados
A transferência de dados pode ser realizada usando as APIs RTCQuicStream para leitura e gravação:
RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);
Armazenando em buffer
As promessas retornadas pelos métodos waitFor*
permitem armazenar dados em buffer quando o JavaScript está ocupado. A pressão de retorno é aplicada no lado de envio quando o
buffer de leitura fica cheio no lado de recebimento. O lado de envio tem um buffer
de gravação que pode ser preenchido quando a pressão de retorno é aplicada. Portanto, o lado de gravação também tem um método waitForWriteBufferedAmountBelow
para
permitir a espera de espaço no buffer para gravação. Mais informações sobre
como gravar/ler dados podem ser encontradas em outras documentação
para desenvolvedores.
Entrega não solicitada/não confiável
Embora um RTCQuicStream
só ofereça suporte ao envio de dados de forma confiável e em ordem,
a entrega não confiável/não ordenada pode ser feita por outros meios. Para
entrega não ordenada, é possível enviar pequenos blocos de dados em fluxos separados
porque os dados não são ordenados entre fluxos. Para entregas não confiáveis, é possível
enviar pequenos blocos de dados com o fim definido como verdadeiro, seguido por uma chamada para
reset()
no stream após um tempo limite. O tempo limite precisa depender de
quantas retransmissões são desejadas antes de descartar os dados.
Quando?
O teste de origem começará na versão do Chrome 73 e será disponibilizado até a versão M75, inclusive. Depois disso, o teste de origem termina. Com base no feedback e no interesse, vamos fazer as mudanças apropriadas e enviar a API, continuar com um novo teste de origem ou descontinuar a API.
Onde?
Navegador Chrome em todas as plataformas exceto iOS.
O que mais?
Feedback
Uma das principais metas do teste de origem é receber feedback de vocês, os desenvolvedores. Temos interesse em:
- O que essa API ativa para você?
- Como essa API melhora outras APIs de transporte de dados
(
WebSocket
s ouRTCDataChannel
do WebRTC)? Como ela poderia melhorar? - Performance
- Ergonomia da API
Registrar-se no teste de origem
- Solicite um token para sua origem.
- Adicione o token às suas páginas. Há duas maneiras de fornecê-lo em
qualquer página da sua origem:
- Adicione uma tag
origin-trial
<meta>
ao cabeçalho de qualquer página. Por exemplo, isso pode ser algo como:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- Se for possível configurar seu servidor, também será possível fornecer o token nas páginas
usando um cabeçalho HTTP
Origin-Trial
. O cabeçalho de resposta resultante precisará ser parecido com este:Origin-Trial: TOKEN_GOES_HERE
- Adicione uma tag
Especificação da Web
O rascunho de especificação foi ultrapassado em relação à API no teste de origem, incluindo:
- Streams unidirecionais que estão mais alinhados com os streams WhatWG
- Como desativar retransmissões
- Datagramas (em breve)
Temos interesse em implementar a especificação completa e muito mais, incluindo o suporte a stream WhatWG, mas queremos ouvir seu feedback primeiro.
Segurança
A segurança no handshake do QUIC é aplicada pelo uso de uma chave pré-compartilhada para estabelecer uma conexão QUIC criptografada do P2P. Essa chave precisa ser sinalizada por um canal fora de banda seguro com garantias de confidencialidade e integridade. A chave ficará exposta ao JavaScript.
Ataque ativo
Ao contrário do DTLS-SRTP, que requer apenas integridade para sinalizar a impressão digital do certificado, a sinalização da chave pré-compartilhada requer integridade e confidencialidade. Se a PSK for comprometida, por exemplo, pelo servidor no canal de sinalização, um invasor ativo poderá montar um ataque "man-in-the-middle" no handshake do QUIC.
Status atual
Step | Status |
---|---|
1. Criar uma explicação | Concluído |
**2a. Especificação RTCQuicTransport ** | **Em andamento** |
**2b. Especificação RTCIceTransport ** | **Em andamento** |
**3. Receba feedback e faça iterações no design** | **Em andamento** |
4. Teste de origem | Começa no Chrome 73. |
5. Iniciar | Not started |
Links úteis
- Outras documentações
- Explicação pública
- Bug de rastreamento
- Solicitar um token de teste de origem
- Como usar um token de teste de origem
- Discussão sobre problemas do RTCQuicTransport
- Discussão sobre problemas do RTCIceTransport