Como depurar o WebRTC

Na Voximplant, usamos o WebRTC desde o seu início: primeiro como uma alternativa ao Flash para chamadas de voz e vídeo e depois como uma substituição completa. A tecnologia percorreu um caminho longo e doloroso de desenvolvimento, apenas recentemente todos os principais navegadores começaram a apoiá-la, há dificuldades com a transferência de tela, vários fluxos de vídeo e, às vezes, o navegador trava simplesmente se você desligar e ativar o fluxo de vídeo. A experiência acumulada nos permite traduzir artigos interessantes para Habr, e hoje passamos a palavra para Xilysys, de Lee Xavier, que irá falar sobre chamadas de depuração (vídeo) no Chrome, Firefox, Safari e Edge. Depurar o WebRTC não é fácil, temos até instruções especiais para remover logs em navegadores populares. E o que Lee tem - você descobrirá sob o corte (spoiler: muito de tudo, incluindo o WireShark).


O lado sombrio do WebRTC


Enquanto trabalhava na Xirsys, vi alguns aplicativos muito legais que usavam o WebRTC. Mas enquanto um pequeno grupo de desenvolvedores cria coisas de alta tecnologia, a maioria dos programadores não consegue nem começar a usar o WebRTC. Porque E tudo é simples. Isso é complicado.

Muitos de nós estamos familiarizados com um aplicativo Web típico. Esse aplicativo possui um cliente que envia solicitações e um servidor que responde a essas solicitações. Um processo simples, linear e facilmente previsível. Se algo der errado, geralmente sabemos onde procurar os logs e o que poderia acontecer. Mas com o WebRTC, nem tudo é tão simples.

Assincronia


Se você já escreveu um aplicativo multithread, provavelmente conhece a dor de cabeça que esse desenvolvimento oferece. Voos, memória ruim - mas na maioria das vezes são apenas erros difíceis de encontrar.

O WebRTC é de natureza assíncrona. E isso não é de todo a simples assincronia AJAX. Para fazer uma analogia, existem várias solicitações AJAX iniciadas simultaneamente que tentam reconciliar dados em dois computadores. Isso ainda é entretenimento.

Campo minado de desvio NAT


A criação de aplicativos da Web se resume ao desenvolvimento de algo que é executado no servidor e responde às solicitações. A pior coisa que pode acontecer é a porta que não está aberta no IPTables. É tratado em 2 minutos. Você não pode dizer sobre o WebRTC.

Servidores da Web, nem mesmo o software, mas o hardware, são dispositivos com endereços IP públicos. Eles são feitos para serem acessíveis de qualquer lugar. E o WebRTC é feito para enviar e receber dados dos computadores dos usuários. Que geralmente têm um endereço IP 192.168, algo que não queima com o desejo de responder a solicitações de rede.

Os autores do WebRTC sabem disso; portanto, o mecanismo classificará diferentes métodos de conexão, na tentativa de estabelecer uma conexão entre dois computadores que não são muito projetados para isso.

Por onde começar a depuração


Neste artigo, falo sobre as ferramentas básicas para resolver os problemas mais populares. Mas antes disso, vamos ver como o WebRTC geralmente estabelece uma conexão.

Como o WebRTC estabelece uma conexão


Todas as conexões WebRTC requerem uma pequena ajuda do protocolo de sinalização. "Pouca ajuda" é seu próprio servidor e protocolo com o qual o chamador poderá se comunicar com a pessoa para quem está ligando antes de estabelecer uma conexão ponto a ponto.

O WebRTC usará o protocolo de sinalização para transmitir informações sobre endereços IP, a capacidade de capturar e reproduzir voz e vídeo, topologia de rede e dados transmitidos.

O protocolo comumente usado é COMET (ou SIP - nota do tradutor) e soquetes da web. O WebRTC não limita os desenvolvedores a nada, então você pode usar o que quiser, pelo menos transferir dados através do Bloco de Notas e copiar e colar (feito em uma das oficinas, funciona - novamente um tradutor). A sinalização conectada aos dois computadores permite iniciar uma conexão já via WebRTC.

Oferta e resposta


As conexões WebRTC usam "oferta" e "resposta":

  1. O iniciador da conexão cria e passa para a "oferta" do outro lado.
  2. A outra parte recebe uma "oferta", cria uma "resposta" e a devolve.
  3. O iniciador da conexão recebe uma "resposta".

Isso está na teoria. Na prática, a troca de cortesias não parece tão simples.

  1. Antes de transmitir a "oferta", o iniciador de conexão cria uma instância do RTCPeerConnection e recebe dele o pacote de texto "SDP" (Session Description Protocol) usando rtcPeerConnection.createOffer () ; Este pacote descreve a capacidade de receber / transmitir voz e vídeo para o navegador.
  2. O conteúdo do pacote SDP é definido como "descrição do lado local da conexão" usando rtcPeerConnection.setLocalDescription () .
  3. O pacote é enviado para o outro lado, onde seu conteúdo é definido como "a descrição do outro lado da conexão" usando rtcPeerConnection.setRemoteDescription () .
  4. No outro lado da conexão, seu próprio pacote SDP é criado usando rtcPeerConnection.createAnswer () , seu conteúdo é definido como a "descrição do lado local da conexão".
  5. O pacote é passado para o iniciador de conexão, que define seu conteúdo como "uma descrição do outro lado da conexão".

E somente depois de todas as ações, as duas partes conectadas conhecem os recursos uma da outra para receber e enviar voz / vídeo.

Candidatos a ICE


Mas a capacidade de trabalhar com a mídia não é suficiente. Afinal, as partes contratantes ainda não disseram nada sobre o estado da rede.

Você pode descobrir quais codecs de vídeo o navegador suporta e se há uma câmera no laptop quase instantaneamente. Leva tempo para descobrir seu endereço IP externo e a lógica da operação NAT, e informações sobre o status da rede são trocadas à medida que essas informações são recebidas.

Graças à tecnologia Trickle ICE (não suportada por todos os navegadores - nota do tradutor), a conexão entre dois dispositivos WebRTC pode ser estabelecida a qualquer momento - assim que um "candidato" adequado for encontrado.

O desenvolvedor deve se inscrever no evento onicecandidate (todas em minúsculas!) E passar os pacotes SDP recebidos para o outro lado, onde precisam ser transmitidos pelo WebRTC usando o método addIceCandidate (e aqui, surpresa, letra maiúscula). Funciona nos dois sentidos.

Ligação


O WebRTC usa coisas como STUN (Utilitários de Traversal de Sessão para NAT) e TURN (Traversal Using Relay around NAT) para estabelecer uma conexão. Parece assustador, mas na realidade existem apenas dois protocolos de rede.

Servidor STUN


O primeiro dos dois protocolos é um pouco mais complicado que o servidor de eco. Quando os participantes da conexão desejam descrever como se conectar a eles, precisam do endereço IP público. E provavelmente não será o endereço IP do computador, os dispositivos públicos raramente são alocados aos dispositivos do usuário. Toda a tecnologia NAT foi inventada para não isolar. Para descobrir ainda o seu endereço público, o navegador faz uma solicitação ao servidor STUN. Passando pelo NAT, o pacote de rede altera seu endereço de retorno para público. Após receber o pacote com a solicitação, o servidor STUN copia o endereço de retorno do pacote para sua carga e envia o pacote de volta. Ao passar pelo NAT na direção oposta, o pacote perde seu endereço IP público, mas uma cópia desse endereço permanece na carga útil, na qual o WebRTC pode lê-lo.


TURN server


O servidor TURN usa a extensão de protocolo STUN. Os mesmos pacotes, cabeçalhos e mais uma coisa nova: comando . O servidor é um proxy: os dois clientes se conectam a ele através da porta de alocação UDP e transmitem seus dados através do servidor.

Os servidores TURN são projetados de forma que o iniciador da conexão tenha mais recursos que o outro lado. Isso leva a um efeito interessante quando uma chamada através de um servidor TURN é bem-sucedida ou não, dependendo de quem está ligando para quem (lembre-se de todo o tradutor de notas do Skype).


Depuração


Então, você leu este parágrafo. Estamos felizes com o tradutor e lembre-se de que o artigo trata da depuração do WebRTC. Mas tudo o que foi dito acima é o mínimo necessário, sem o qual você nem pode começar. Mas se você começar, e você não tiver sorte desumana, ela será quebrada.

Vai quebrar de muitas maneiras diferentes. O primeiro é a falta de conectividade. Você passou as configurações do servidor STUN e TURN para os dois WebRTCs, ajudou-os a trocar candidatos de ofertas, respostas e ICE, mas não há vídeo ou voz. Por onde começar? Com problemas de reprodução local.

Depuração local do WebRTC


Como escrevi acima, o principal trabalho do WebRTC ocorre no lado do navegador. Os servidores STUN e TURN são incrivelmente simples, portanto, a maioria dos problemas ocorre no seu código JavaScript, executado em dois navegadores. Triste, mas é verdade. Por outro lado, se a coisa mais interessante acontecer localmente nos navegadores, você terá amplas oportunidades para depuração!

A primeira coisa a verificar é a sua sinalização. É o seu código que transmite a configuração do áudio com vídeo (oferta, resposta) e informações sobre configurações de rede (candidatos a gelo) entre navegadores. Você precisa verificar quais pacotes foram enviados, quais receberam e transmitiram o WebRTC:

  • o outro lado da conexão recebeu uma oferta? O iniciador da conexão recebeu uma resposta? Uma conexão não será estabelecida sem essa troca mínima de comodidades;
  • O WebRTC nas duas extremidades da conexão passou os pacotes com os candidatos a ICE? Você trocou esses pacotes e os passou de volta para o lado oposto usando addIceCandidate ?
  • se tudo correu bem com a troca de pacotes, o manipulador de eventos onaddstream foi chamado e você instalou o objeto resultante em um elemento HTML para reproduzir vídeo (ou áudio)?

Se a troca de pacotes não for suspeita, você poderá se aprofundar nos detalhes da sessão.

Protocolo de descrição da sessão


Os pacotes de oferta, resposta e candidato a ICE são criados pelo WebRTC no formato de texto SDP. À primeira vista, o conteúdo dos pacotes parece assustador, mas com um pouco de preparação, você pode obter muitos benefícios deles durante a depuração. A Wikipedia descreve o SDP muito bem, mas achei uma descrição melhor para você.

O campo mais importante nos pacotes SDK ICE candidatos é tip . Para o WebRTC, um campo pode ter um dos três valores:

  • tipo host;
  • typ srflx;
  • tipo relé.

tipo host


O tipo de host especifica o candidato a ICE para uma conexão de área local (o WebRTC enumera vários candidatos na esperança de estabelecer uma conexão, não se sabe com antecedência qual deles será apresentado - nota pelo tradutor). Essa conexão não requer um servidor STUN ou TURN, pois os dispositivos na rede local geralmente podem estabelecer conexões de rede diretamente. Ao depurar a partir da rede local, basta verificar e depurar a transmissão de pacotes do host e garantir que os dispositivos possam enviar pacotes UDP entre si. Embora existam exceções, na prática eu vi configurações de rede nas quais o navegador precisava de um servidor TURN para se conectar ... a si próprio.

typ srflx


A combinação de letras “srflx” significa “Server Reflexive” e marca os candidatos à conexão usando um endereço IP externo, onde um servidor STUN é suficiente para conexão (usando a tecnologia de penetração NAT, que é bem-sucedida em cerca de 80% dos casos, observe o tradutor).

tipo relé


"Relay" marca a conexão através de um servidor TURN, que quase sempre é bem-sucedido. É importante lembrar que o WebRTC não é necessário para criar exatamente três pacotes diferentes com o campo "typ"; como os candidatos são selecionados depende da implementação do WebRTC em uma versão específica do navegador.

Testando a conectividade do dispositivo


O Google oferece um aplicativo da web dedicado para testar conexões WebRTC no seu dispositivo. Abra a página, clique no botão "Iniciar" e o código JavaScript tentará estabelecer uma conexão com o servidor do Google usando sinalização, os servidores STUN e TURN do Google.

WebRTC Internals


Você examinou todos os pacotes, verificou o código, tudo parece correto, mas não funciona? Nesses casos, o Google forneceu ao navegador Chrome uma seção especial que mostra os elementos internos do WebRTC durante a configuração da conexão e alguns gráficos bonitos no caso de uma conexão bem-sucedida. Para usar, abra um link técnico especial no navegador:

chrome://webrtc-internals

Se você já possui um aplicativo usando o WebRTC aberto, verá imediatamente um monte de dados técnicos. Caso contrário, basta abrir outra guia e há algo nela que usa o WebRTC. A guia exibe todas as chamadas para o objeto RTCPeerConnection e permite ver em tempo real como a conexão é estabelecida.

Configuração do ICE


No topo da página está a sequência ICE que foi usada para inicializar a conexão. Se um erro foi cometido durante sua formação, isso será imediatamente visível (pela "linha ICE", o autor se refere à configuração do objeto RTCPeerConnection com uma lista de servidores STUN e TURN (o objeto 'iceServers') - observação pelo tradutor). Talvez não haja uma lista de servidores? Você deve configurar o objeto RTCPeerConnection antes de fazer a primeira chamada para createOffer ou createAnswer .


Eventos RTCPeerConnection


A próxima seção interna mostra as chamadas para os métodos RTCPeerConnection e os eventos recebidos do objeto em ordem cronológica. Os erros são cuidadosamente destacados em vermelho. Observe que o addIceCandidateFailed vermelho geralmente não é sinal de erro e a conexão pode ser estabelecida normalmente. Se a conexão for bem-sucedida, o último evento na lista será um evento iceconnectionstatechange com o valor complete .

Seção 'estatísticas'


A próxima seção é relevante quando a conexão é estabelecida com sucesso. Ele contém estatísticas de dados transmitidos e atrasos na rede. As duas opções mais interessantes são: ssrc e bweforvideo .

  • ssrc , "Stream Source", marca cada uma das suas faixas de áudio e vídeo. Exibe estatísticas de dados e parâmetros transmitidos, como tempo de ida e volta ;
  • bweforvideo , BandWidth Estimate, exibe a largura do canal de rede usado.


Função GetStats


Freqüentemente, você não poderá acessar a página interna. Por exemplo, quando ocorre um problema com seu usuário. Nesse caso, você pode obter os mesmos dados mostrados na página interna chamando o método getStats no objeto RTCPeerConnection . Este método configura uma função de retorno de chamada que o WebRTC chamará sempre que algo interessante acontecer. A função chamada obtém um objeto com os campos que a página interna exibe:

 rtcPeerConnection.getStats(function(stats) { document.getElementById("lostpackets").innerText = stats.packetsLost; }); 

Outra ferramenta útil é o evento oniceconnectionstatechange de um objeto RTCPeerConnection . O manipulador de eventos receberá informações sobre o andamento da conexão. Possíveis opções:

  • novo : o WebRTC espera candidatos do segundo lado da conexão, que devem ser adicionados usando o método addIceCandidate ;
  • verificação : o WebRTC recebeu candidatos do segundo lado da conexão, os compara com os locais e itera sobre as opções;
  • conectado : um par adequado de candidatos é selecionado e a conexão é estabelecida. Vale ressaltar que, depois disso, os candidatos poderão continuar a comparecer, de acordo com o protocolo Trickle ICE;
  • concluído : todos os candidatos são recebidos e a conexão é estabelecida.
  • desconectado : a conexão está desconectada . Em canais instáveis, o WebRTC é capaz de se reconectar, monitoramos o sinalizador conectado ;
  • fechado : a conexão está desconectada e o WebRTC não funciona mais com ela.

Se a conexão terminou no estado de falha , podemos examinar os candidatos recebidos de ambos os lados e entender por que a conexão falhou. Por exemplo, se um lado forneceu candidatos a host e srflx , o outro lado hospedou e retransmitiu , mas os dispositivos estavam em redes diferentes.

Retângulo preto em vez de vídeo


Geralmente, há uma situação em que a conexão é estabelecida, o som é transmitido, mas, em vez do vídeo, um ou ambos os participantes têm um retângulo preto. Na maioria das vezes, isso acontece se você atribuir o objeto de vídeo recebido a um elemento HTML antes que a conexão faça a transição para o estado concluído .

Como cutucar uma varinha fora


Além do próprio objeto RTCPeerConnection e dos internos exibidos pelo navegador, você pode usar ferramentas de análise de pacotes de rede, como o Wireshark. Essas ferramentas podem exibir pacotes de protocolos WebRTC usados. Por exemplo, o Wireshark mostrará o conteúdo dos pacotes STUN na janela principal e você poderá filtrá-los digitando a palavra-chave “stun” no campo de filtro:


O que ver nas respostas do servidor? Se você vir apenas respostas com o tipo de Ligação , isso significa que apenas STUN (conversa de IP externo) é suportada e o WebRTC pode oferecer apenas candidatos srflx . Se as respostas contiverem pacotes específicos para TURN, Allocation e CreatePermission , o WebRTC terá a oportunidade de tentar se conectar através de um servidor proxy. O analisador de pacotes marca uma alocação bem-sucedida e malsucedida. Se não houver nenhum êxito, provavelmente os parâmetros de acesso incorretos aos servidores TURN (que quase sempre protegem com um nome de usuário e senha - a nota do tradutor) são passados.

Se houver um pacote CreatePermission Success Response no log, podemos assumir que tudo está bem com as configurações STUN e TURN. E se também houver um pacote ChannelBind , foi possível estabelecer uma conexão com o servidor TURN em alta velocidade.

Cellular Issues


Na minha prática, muitas soluções WebRTC que estabelecem uma conexão WiFi não podem se conectar via 3G / 4G. Uma aplicação lançada em um dispositivo móvel é mais difícil de depurar: não temos um analisador de pacotes tão simples como o Wireshark e o Safari não pode mostrar os internos do WebRTC. A lógica sugere que, se o aplicativo funciona bem via WiFi, o problema não está no aplicativo em si, mas na comunicação celular. Como depurar? Pegue um laptop e conecte um dongle 3G a ele. Portanto, você possui um analisador de pacotes e logs convenientes com os quais pode encontrar a raiz de todos os problemas em um tempo razoável.

Conclusões


Depurar o WebRTC não é fácil, mas se você pesquisar bem na Internet, poderá encontrar muitos artigos e exemplos. Se você trabalha no campo das comunicações em tempo real, recomendo que você leia as especificações RFC dos protocolos STUN , TURN e tecnologia WebRTC . Os documentos são grandes, mas as informações contidas neles ajudam a tomar decisões confiáveis ​​e a responder à pergunta "por que não soa"?

Source: https://habr.com/ru/post/pt417869/


All Articles