WebRTC através do Kurento: Experiência de Teste e Implementação


Neste artigo, compartilharei minha experiência com a tecnologia WebRTC e o servidor de mídia Kurento durante a fase de teste e implementação. Vou lhe contar quais os problemas que encontrei e como os resolvi. Não falarei sobre como desenvolver um aplicativo do zero, mas darei muitos links úteis. Estou certo de que minha história será útil para quem vai trabalhar com o WebRTC.

1. Introdução


O Sistema de Informações Médicas (MIS), que está sendo desenvolvido por nossa empresa, já se tornou um grande projeto corporativo com muitos microsserviços, barramentos de mensagens, clientes móveis e assim por diante. Algumas partes do sistema devem ser concedidas para desenvolvimento e suporte a organizações de terceiros, uma vez que não são o nosso perfil.

O serviço de telemedicina é um desses módulos MIS. Não havia experiência no desenvolvimento de videoconferência e no uso do WebRTC, e o pedido foi delegado. Mas, após algum tempo, devido a várias circunstâncias, essa empresa parou de oferecer suporte à videoconferência. Sem suporte, este serviço foi desativado e "acumulando poeira" no repositório.

E agora é hora de reviver esse micro serviço. Foi decidido tentar reiniciar a telemedicina por conta própria. Nossa empresa cresceu, surgiram mais especialistas - é possível e necessário dominar novos tópicos para o desenvolvimento. Eu não havia participado da transmissão de vídeo antes, mas era muito interessante entender e estudar uma tecnologia tão promissora como o WebRTC.

Aqui estão alguns links muito úteis sobre a tecnologia WebRTC e o servidor Kurento que me ajudaram desde o início:


Introdução


A tarefa era simples: restaurar o sistema de videoconferência existente, fazer um inventário do que já havia sido feito antes e, se necessário, modificá-lo de acordo com os desejos dos usuários. Os primeiros testes em máquinas virtuais e computadores reais foram bem-sucedidos. Mas a implantação do sistema no cliente trouxe muitos problemas.

Deixe-me lembrá-lo de que o cliente já possui um sistema de informações médicas (MIS) que abrange um grande número de tarefas: da fila eletrônica, local de trabalho do médico, gerenciamento de documentos e PACS ao subsistema de gerenciamento de equipamentos médicos.

Quando se tornou necessário desenvolver a funcionalidade de videoconferência para conectar a equipe médica dos centros de diagnóstico (doravante denominada CD) a pacientes remotos, dois pré-requisitos foram estabelecidos:

Todas as conferências devem ser gravadas e armazenadas no servidor.

Os pacientes não devem instalar nenhum programa adicional em seus dispositivos, exceto o navegador, que na maioria dos casos já está pré-instalado.

O WebRTC funciona a partir de um navegador sem programas ou plug-ins adicionais. E o Kurento pode gravar tudo o que passa por ele. Além disso, este servidor de mídia possui um bom conjunto de bibliotecas prontas para trabalhar com sua API através de Java e JavaScript, o que simplifica bastante o desenvolvimento.

O desenvolvimento da parte do servidor, ou melhor, sua base, mesmo antes de iniciar a tarefa, foi transferido pelo cliente para uma empresa de terceirização para uma empresa de terceiros. Portanto, havia um "Managing Server" (CSS) - uma base de servidores pronta para uso, que eu obtive para implementação.

A ideia geral de interação inicialmente era assim:



Mas, no processo de trabalho adicional, todo o sistema mudou e se tornou mais complicado.

Primeira experiência de ressuscitação


Após a implantação em uma rede de teste em máquinas virtuais e em vários computadores "ativos", muitos testes e experimentos foram realizados - tudo funcionou perfeitamente. Assim, chegou a hora de introduzir uma rede de trabalho real.

Para o teste, uma vítima responsável na forma de um médico e seu local de trabalho foi designada para me ajudar. E a segunda chamada através do microsserviço de telemedicina caiu!

É bom que isso tenha acontecido durante o teste beta e, além de mim e um médico que estava satisfeito com as aventuras, ninguém viu isso.

O que está acontecendo e por que a conexão não está sendo estabelecida foi muito difícil de entender. O WebRTC não mostra falhas - apenas espera que um sinal apareça. Inconscientemente, foi muito difícil depurar de alguma forma: a parte do servidor está funcionando bem, o Kurento está silencioso nos logs, os clientes estão aguardando o fluxo, mas nada acontece.

Habr ajudou (louvado seja ele):


É uma pena que eu não conhecia essas ferramentas antes.

Após analisar os dados do log e observar o status das conexões, ficou claro que os scripts do lado do servidor e do cliente não têm reação aos eventos no sistema WebRTC. E onde conseguir esses eventos?

Os desenvolvedores do servidor kurento fornecem uma biblioteca JavaScript muito conveniente para trabalhar com o WebRTC: kurento-utils.js.

Para iniciar rapidamente, basta criar um objeto:

new kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options, callback()); 

E, para acessar eventos, é necessário redefinir os métodos internos da biblioteca. Simplifiquei o código o máximo possível para torná-lo mais claro:

 //    WebRtcPeerRecvonly var options = { //      peerConnection: getRTCPeerConnection(videoId), remoteVideo: videoElement, // //  ICE  onicecandidate: function (candidate) { onIceCandidate(candidate, videoId, true); }, onerror: onError, //   mediaConstraints: { //  video: true, audio: true} }; //  WebRTC incomeWebRtc[videoId] = new kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly( options, function (error) { if (error) { return console.error(error); } this.generateOffer( function (error, sdpOffer) { //  }); }); //      function getRTCPeerConnection( videoId ){ var configuration = { "iceServers": [ {"url": "stun:" + stunServer}, {"url": "turn:" + turnServer, credential: turnCredential, username: turnUsername} ] }; var mypc = new RTCPeerConnection(configuration); //      mypc.oniceconnectionstatechange = function(){ state = this.iceConnectionState; console.info("### iceConnectionState " + videoId + " > " + this.iceConnectionState); }; mypc.onsignalingstatechange = function(){ state = this.signalingState || this.readyState; console.info("### SignalingState " + videoId + " > " + state); }; mypc.onconnectionstatechange = function(){ console.info("### ConnectionState " + videoId + " > " + this.connectionState); }; return mypc; } 

Falando de certificados


Como o artigo é sobre minha experiência, compartilharei informações de que os navegadores modernos se tornaram muito rígidos em relação à segurança. Se o recurso tiver um certificado autoassinado, mesmo com permissão especial, o navegador proíbe o acesso aos periféricos do computador.

Você pode criar um certificado com recursos gratuitos na Internet e configurar uma rede local para seu uso, ou baixar o Firefox versão 65 ou superior.Nesta versão, basta clicar no botão, que concordo com os riscos de certificados autoassinados e acessar câmeras e microfones.

Dessa forma, parecia mais fácil para mim.

Segundo teste (já cuidadoso)


Pareceu-me que o médico iria concorrer a pipoca quando me visse no próximo teste. Ele claramente gostava de me ver lutando com a tecnologia moderna.

De fato, essa atualização do sistema não foi uma versão, porque eu não consertei nada, nem sabia a causa dos problemas. Repito que tudo funcionou perfeitamente no escritório. O código adicionou reações a todos os eventos que geraram o WebRTC e o Kurento, aos quais eu cheguei, e tudo isso foi escrito em grandes detalhes nos logs. Até coloquei meus logs em arquivos separados para que não fossem confundidos com os principais do IIA.

Juntamente com um médico especialista e um administrador de sistemas clientes, tentamos o sistema. Eles nem testaram, a saber, "torturados". Criamos videoconferências em todos os modos possíveis e em todos os dispositivos disponíveis. Outros médicos e parte da equipe do escritório remoto estavam envolvidos neste jogo.

O principal era não verificar o sistema (não funcionava), mas coletar o máximo de dados possível. Como resultado, verificou-se que:

  1. Aproximadamente 80% das tentativas de criar uma videoconferência são bem-sucedidas.
  2. Algumas conexões que usam candidatos ICE para IPv6 não funcionam.
  3. Dos 5 operadores móveis, apenas 2 funcionaram.

Tudo ficou simples: você não pode ir muito longe apenas no Google


A análise das informações coletadas mostrou que a conexão através do servidor TURN do Google é instável. Ou a carga neles é grande ou é apenas um servidor de demonstração para quem está começando a aprender a tecnologia. Mas como um fato: falhas muito frequentes. Precisa do seu próprio servidor TURN / STUN!

O segundo motivo para as falhas são os endereços IPv6.local. O servidor kurento não aceita candidatos a ICE com esses endereços. É bom que antes de enviar todos os candidatos a ICE passem pelo código em minhas mãos e acabei de filtrar o IPv6.local.

O problema das operadoras móveis é resolvido, novamente, com seu servidor TURN / STUN.
Em três de cada cinco operadoras móveis, o NAT é simétrico e o WebRTC não pode avançar. Mais detalhes podem ser encontrados aqui: O NAT simétrico é terrível?

É uma pena que meu celular pessoal funcione no cartão SIM de uma operadora que não se incomodou com a proteção simétrica. Portanto, meu teste inicial não revelou esse problema.


Servidor TURN / STUN


O pacote resiprocate-turn-server foi escolhido como servidor.

Eles não escolheram por um longo tempo - está no repositório padrão do ubuntu - instalação fácil e atualizações automáticas. Mas não é muito conveniente trabalhar com contas para conectar-se: logins e senhas são retirados apenas do arquivo, e é por isso que você precisa criar um utilitário ou script adicional para exportar do banco de dados do servidor principal.

No momento, esse arquivo é gerado manualmente e as contas são distribuídas por um simples conjunto de senhas. A autorização é implementada através do servidor principal do MIS, para que a segurança não seja comprometida. Mas a estrutura geral de todo o sistema parece feia. Os planos para refazer esse momento.

Terceira viagem ao cliente


Corrigi o código, instalei e configurei meu servidor TURN / STUN, desenvolvi um pool de senhas e as distribuí para os clientes no início de uma videoconferência e, após atualizar os servidores de produção, fui a um médico que eu já conhecia.

Isso funciona! Viva! Todas as conferências iniciadas são bem-sucedidas em todos os dispositivos e em todos os modos: o paciente da conta pessoal pode ligar para o médico, o terapeuta durante a recepção pode ligar para o diagnóstico funcional para consultas adicionais, e os próprios médicos podem organizar uma videoconferência para vários usuários de diferentes ramos da cidade.

Já ensinados por uma experiência amarga, nos envolvemos em testes meticulosos com a criação artificial de situações de emergência. No tópico deste artigo, enfatizo a necessidade de definir um limite no tempo de espera da conexão. O WebRTC, junto com o Kurento, estão esperando a transmissão começar infinitamente e esperam que os bytes de vídeo estejam prestes a ir. Eu tive que definir um timer para 10 segundos, o que gera um erro no servidor de gerenciamento se os bytes nunca chegarem.

Depois de todas as melhorias


Finalmente, o sistema está funcionando e funcionando bem. As primeiras críticas foram enviadas por usuários em campo. E imediatamente um grande número de desejos e sugestões de design, funções adicionais e outros planos para desenvolvimento adicional apareceram. O trabalho começou a ferver com vigor renovado!

Agora, a topologia completa do sistema fica assim:


RESULTADOS:


Em conclusão, quero dizer o seguinte:

Em primeiro lugar, o WebRTC é uma excelente tecnologia com grandes perspectivas, mas é muito difícil testá-lo e depurá-lo. Antes de iniciar o desenvolvimento, é imperativo implantar uma rede com todos os tipos de conexões que o cliente possa ter. E a depuração pela janela de informações do navegador não é uma ferramenta muito conveniente.

Em segundo lugar, elogios a Habru! Enquanto trabalhava neste projeto, encontrei muitas informações sobre este recurso. Todos os links deste artigo levam a ele.

Foi decidido deixar o projeto de videoconferência de telemedicina para suporte e desenvolvimento em nossa organização; não o terceirizaremos. No futuro, ainda há muito trabalho:


TUDO


Estou certo de que minha experiência será útil não apenas para desenvolvedores sob WebRTC + Kurento, mas também para aqueles que começarão a implementar projetos igualmente complexos. Preste mais atenção ao teste em condições o mais próximo possível da realidade.

E leve em consideração os riscos que as equipes de suporte de seus microsserviços podem "desaparecer" repentinamente - essa é uma tarefa muito inesperada e desagradável.

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


All Articles