Publicado em: 4 de novembro de 2013
O WebRTC permite a comunicação ponto a ponto. Ele requer servidores para que os clientes possam trocar metadados e coordenar a comunicação por um processo chamado sinalização. Os servidores também ajudam os clientes a lidar com conversores de endereços de rede (NATs) e firewalls.
Aqui, você vai aprender a criar um serviço de sinalização e lidar com as peculiaridades da conectividade do mundo real com servidores STUN e TURN. Você também vai entender como os apps WebRTC podem lidar com chamadas de várias partes e interagir com serviços, como VoIP e PSTN (também conhecidos como telefones).
O que é sinalização?
A sinalização é o processo de coordenação da comunicação. Para que um app WebRTC configure uma chamada, os clientes precisam trocar as seguintes informações:
- Mensagens de controle de sessão usadas para abrir ou fechar a comunicação
- Mensagens de erro
- Metadados de mídia, como codecs, configurações de codec, largura de banda e tipos de mídia
- Dados de chave usados para estabelecer conexões seguras
- Dados de rede, como o endereço IP e a porta de um host, conforme vistos pelo mundo externo
Esse processo de sinalização precisa de uma maneira para que os clientes transmitam mensagens. Esse mecanismo não é implementado pelas APIs WebRTC. Em vez disso, você precisa criá-lo.
Por que a sinalização não é definida pelo WebRTC?
Para evitar redundância e maximizar a compatibilidade com tecnologias estabelecidas, os métodos e protocolos de sinalização não são especificados pelos padrões do WebRTC. Essa abordagem é descrita pelo Protocolo de estabelecimento de sessão JavaScript (JSEP, na sigla em inglês):
A arquitetura do JSEP também evita que um navegador precise salvar o estado, ou seja, funcionar como uma máquina de estado de sinalização. Isso seria problemático se, por exemplo, os dados de sinalização fossem perdidos sempre que uma página fosse recarregada. Em vez disso, o estado de sinalização pode ser salvo em um servidor.
O JSEP exige a troca entre os pares de oferta e resposta, os metadados de mídia. As ofertas e respostas são comunicadas no formato Session Description Protocol (SDP), que tem esta aparência:
v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2
...
Quer saber o que significa todo esse jargão do SDP? Confira os exemplos da Internet Engineering Task Force (IETF).
Lembre-se de que o WebRTC foi projetado para que a oferta ou a resposta possa ser ajustada
antes de ser definida como a descrição local ou remota, editando os valores no
texto do SDP. Por exemplo, a função preferAudioCodec() em
appr.tc pode ser usada para definir o codec e a taxa de bits padrão. O SDP
é um pouco difícil de manipular com JavaScript, e há discussões sobre
se as versões futuras do WebRTC devem usar JSON, mas há
algumas vantagens
em manter o SDP.
API RTCPeerConnection e sinalização: oferta, resposta e candidato
RTCPeerConnection é a API usada por apps WebRTC para criar uma conexão
entre pares e comunicar áudio e vídeo.
Para inicializar esse processo, o RTCPeerConnection tem duas tarefas:
- Verifique as condições de mídia local, como recursos de resolução e codec. Esses são os metadados usados para o mecanismo de oferta e resposta.
- Receber possíveis endereços de rede para o host do app, conhecidos como candidatos.
Depois que esses dados locais forem determinados, eles precisarão ser trocados por um mecanismo de sinalização com o par remoto.
Imagine que Alice está tentando ligar para Eva. Veja o mecanismo de resposta completo em todos os detalhes:
- Alice cria um objeto
RTCPeerConnection. - Alice cria uma oferta (uma descrição de sessão SDP) com o
método
RTCPeerConnectioncreateOffer(). - Alice liga para
setLocalDescription()com a oferta dela. - Alice transforma a oferta em string e usa um mecanismo de sinalização para enviá-la a Eve.
- Eve chama
setRemoteDescription()com a oferta de Alice para que oRTCPeerConnectiondela saiba sobre a configuração de Alice. - Eva chama
createAnswer(), e o callback de sucesso para isso recebe uma descrição de sessão local: a resposta de Eva. - Eva define a resposta como a descrição local chamando
setLocalDescription(). - Em seguida, Eve usa o mecanismo de sinalização para enviar a resposta em string para Alice.
- Alice define a resposta de Eve como a descrição da sessão remota usando
setRemoteDescription().
Alice e Eve também precisam trocar informações de rede. A expressão "encontrar candidatos" se refere ao processo de encontrar interfaces de rede e portas usando o framework ICE.
- Alice cria um objeto
RTCPeerConnectioncom um gerenciadoronicecandidate. - O gerenciador é chamado quando os candidatos de rede ficam disponíveis.
- No gerenciador, Alice envia dados de candidatos em formato de string para Eve pelo canal de sinalização.
- Quando Eve recebe uma mensagem de candidato de Alice, ela chama
addIceCandidate()para adicionar o candidato à descrição do par remoto.
O JSEP é compatível com o ICE Candidate Trickling, que permite que o autor da chamada forneça candidatos de forma incremental ao destinatário após a oferta inicial, e que o destinatário comece a agir na chamada e configure uma conexão sem esperar que todos os candidatos cheguem.
Codificar o WebRTC para sinalização
O snippet de código a seguir é um exemplo de código do W3C que resume o processo de sinalização completo. O código pressupõe a existência de algum mecanismo de sinalização, SignalingChannel. A sinalização será discutida em mais detalhes posteriormente.
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// send the offer to the other peer
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// After remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
Para ver os processos de oferta-resposta e troca de candidatos em ação, acesse
simpl.info RTCPeerConnection e confira
o registro do console para um exemplo de chat por vídeo de página única. Você pode baixar um
dump completo de sinalização e estatísticas do WebRTC na página about://webrtc-internals
no Google Chrome ou na página opera://webrtc-internals no Opera.
Descoberta de semelhantes
Essa é uma forma sofisticada de perguntar: "Como faço para encontrar alguém com quem conversar?"
Para ligações, você tem números de telefone e listas telefônicas. Para chat por vídeo e mensagens on-line, você precisa de sistemas de gerenciamento de identidade e presença, além de uma maneira para os usuários iniciarem sessões. Os apps WebRTC precisam de uma maneira para que os clientes sinalizem uns aos outros que querem iniciar ou participar de uma chamada.
Os mecanismos de descoberta de peering não são definidos pelo WebRTC, e não vamos entrar nas opções aqui. O processo pode ser tão simples quanto enviar um URL por e-mail ou mensagem. Para apps de chat por vídeo, como Talky, tawk.to e Browser Meeting, você convida pessoas para uma chamada compartilhando um link personalizado. O desenvolvedor Chris Ball criou um experimento intrigante de WebRTC sem servidor que permite que os participantes de chamadas WebRTC troquem metadados por qualquer serviço de mensagens que quiserem, como mensagens instantâneas, e-mail ou pombo-correio.
Como criar um serviço de sinalização?
Para reiterar, os protocolos e mecanismos de sinalização não são definidos pelos padrões do WebRTC. Seja qual for sua escolha, você precisa de um servidor intermediário para trocar mensagens de sinalização e dados do app entre clientes. Infelizmente, um app da Web não pode gritar na Internet: "Conecte-me ao meu amigo!"
Felizmente, as mensagens de sinalização são pequenas e trocadas principalmente no início de uma chamada. Em testes com appr.tc para uma sessão de chat por vídeo, um total de cerca de 30 a 45 mensagens foi processado pelo serviço de sinalização, com um tamanho total de cerca de 10 KB para todas as mensagens.
Além de não exigirem muita largura de banda, os serviços de sinalização do WebRTC não consomem muito processamento ou memória, porque só precisam retransmitir mensagens e reter uma pequena quantidade de dados de estado da sessão, como quais clientes estão conectados.
Enviar mensagens do servidor para o cliente
Um serviço de mensagens para sinalização precisa ser bidirecional: do cliente para o servidor e do servidor para o cliente. A comunicação bidirecional vai contra o modelo de solicitação/resposta do cliente HTTP/servidor, mas vários hacks, como long polling, foram desenvolvidos ao longo de muitos anos para enviar dados de um serviço em execução em um servidor da Web para um app da Web em execução em um navegador.
A API EventSource
permite eventos enviados pelo servidor, dados enviados de um servidor da Web para um cliente do navegador
por HTTP. O EventSource foi projetado para mensagens unidirecionais, mas pode ser
usado em combinação com o XHR para criar um serviço de troca de mensagens
de sinalização. Um serviço de sinalização transmite uma mensagem de um autor de chamada, entregue por solicitação XHR, enviando-a por push pelo EventSource para o destinatário.
O WebSocket foi projetado para comunicação full-duplex
entre cliente e servidor, o que significa que as mensagens podem fluir em ambas as direções ao
mesmo tempo. Uma vantagem de um serviço de sinalização criado com WebSocket puro ou
eventos enviados pelo servidor (EventSource) é que o back-end dessas APIs pode ser
implementado em uma variedade de frameworks da Web comuns à maioria dos pacotes de hospedagem na Web
para linguagens como PHP, Python e Ruby.
Todos os navegadores que oferecem suporte ao WebRTC também oferecem suporte ao WebSocket. O TLS precisa ser usado em todas as conexões para garantir que as mensagens não sejam interceptadas sem criptografia e também para reduzir problemas com a travessia de proxy. Para mais informações sobre WebSocket e travessia de proxy, leia o capítulo sobre WebRTC no livro High Performance Browser Networking, de Ilya Grigorik.
É possível lidar com a sinalização fazendo com que os clientes do WebRTC pesquisem um servidor de mensagens repetidamente pelo Ajax, mas isso gera muitas solicitações de rede redundantes, o que é especialmente problemático para dispositivos móveis. Mesmo depois que uma sessão é estabelecida, os pares precisam consultar as mensagens de sinalização em caso de mudanças ou encerramento da sessão por outros pares. O exemplo de app WebRTC Book usa essa opção com algumas otimizações para a frequência de sondagem.
Sinalização de escala
Embora um serviço de sinalização consuma relativamente pouca largura de banda e CPU por cliente, os servidores de sinalização de um app conhecido podem ter que lidar com muitas mensagens de locais diferentes com altos níveis de simultaneidade. Os apps WebRTC que recebem muito tráfego precisam de servidores de sinalização capazes de lidar com uma carga considerável. Não vamos entrar em detalhes aqui, mas há várias opções para mensagens de alto volume e alto desempenho, incluindo as seguintes:
O eXtensible Messaging and Presence Protocol (XMPP) é um protocolo desenvolvido para mensagens instantâneas que pode ser usado para sinalização. As implementações de servidor incluem ejabberd e Openfire. Os clientes JavaScript, como o Strophe.js, usam BOSH para emular o streaming bidirecional, mas o BOSH pode ser ineficiente e ter uma escalonabilidade ruim em comparação com o WebSocket.
Bibliotecas de código aberto, como ZeroMQ (usada pela TokBox para o serviço Rumour) e OpenMQ (NullMQ aplica conceitos do ZeroMQ a plataformas da Web usando o protocolo STOMP no WebSocket).
Plataformas comerciais de mensagens na nuvem que usam WebSocket (embora possam voltar para a sondagem longa), como Pusher e Kaazing.
Plataformas comerciais de WebRTC, como o vLine
Criar um serviço de sinalização com o Socket.io no Node
Veja a seguir o código de um app da Web que usa um serviço de sinalização criado com o Socket.io no Node. O design do Socket.io facilita a criação de um serviço para trocar mensagens, e o Socket.io é particularmente adequado para a sinalização do WebRTC devido ao conceito integrado de salas. Este exemplo foi projetado para um número relativamente pequeno de usuários, em vez de uso em produção.
O Socket.io usa o WebSocket com substitutos: sondagem longa AJAX, streaming de várias partes AJAX, Forever Iframe e sondagem JSONP. Ele foi portado para vários back-ends, mas talvez seja mais conhecido pela versão do Node usada neste exemplo.
Não há WebRTC neste exemplo. Ele foi projetado para mostrar como criar sinalização em um app da Web. Confira o registro do console para ver o que acontece quando os clientes entram em uma sala e trocam mensagens. Este codelab do WebRTC oferece instruções detalhadas sobre como integrar isso a um app de chat por vídeo completo do WebRTC.
Este é o cliente index.html:
<!DOCTYPE html>
<html>
<head>
<title>WebRTC client</title>
</head>
<body>
<script src='/socket.io/socket.io.js'></script>
<script src='js/main.js'></script>
</body>
</html>
Este é o arquivo JavaScript main.js referenciado no cliente:
const isInitiator;
room = prompt('Enter room name:');
const socket = io.connect();
if (room !== '') {
console.log('Joining room ' + room);
socket.emit('create or join', room);
}
socket.on('full', (room) => {
console.log('Room ' + room + ' is full');
});
socket.on('empty', (room) => {
isInitiator = true;
console.log('Room ' + room + ' is empty');
});
socket.on('join', (room) => {
console.log('Making request to join room ' + room);
console.log('You are the initiator!');
});
socket.on('log', (array) => {
console.log.apply(console, array);
});
Confira o app de servidor completo:
const static = require('node-static');
const http = require('http');
const file = new(static.Server)();
const app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2013);
const io = require('socket.io').listen(app);
io.sockets.on('connection', (socket) => {
// Convenience function to log server messages to the client
function log(){
const array = ['>>> Message from server: '];
for (const i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', (message) => {
log('Got message:', message);
// For a real app, would be room only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', (room) => {
const numClients = io.sockets.clients(room).length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room ' + room);
if (numClients === 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients === 1) {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
} else { // max two clients
socket.emit('full', room);
}
socket.emit('emit(): client ' + socket.id +
' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id +
' joined room ' + room);
});
});
Para executar esse app no localhost, você precisa ter o Node.js,
o Socket.IO e o node-static. Para
instalar o Socket.IO e o node-static, execute npm em um terminal
no diretório do app:
npm install socket.io
npm install node-static
Para iniciar o servidor, execute o seguinte comando em um terminal no diretório do app:
node server.js
No navegador, abra localhost:2013. Abra uma nova guia ou janela em qualquer
navegador e abra localhost:2013 novamente. Para ver o que está acontecendo, verifique o
console. No Chrome e no Opera, é possível acessar o console pelas Ferramentas para desenvolvedores do Google Chrome com Ctrl+Shift+J (ou Command+Option+J no Mac).
Seja qual for a abordagem escolhida para a sinalização, o back-end e o app cliente precisam fornecer serviços semelhantes aos deste exemplo.
Pegadinhas de indicadores
- O
RTCPeerConnectionnão vai começar a coletar candidatos até quesetLocalDescription()seja chamado. Isso é obrigatório no rascunho do JSEP IETF. - Aproveite o Trickle ICE. Chame
addIceCandidate()assim que os candidatos chegarem.
Servidores de sinalização prontos
Se você não quiser criar o seu, há vários servidores de sinalização WebRTC disponíveis, que usam o Socket.IO como no exemplo anterior e são integrados às bibliotecas JavaScript do cliente WebRTC:
- webRTC.io é uma das primeiras bibliotecas de abstração para WebRTC.
- O Signalmaster é um servidor de sinalização criado para uso com a biblioteca de cliente JavaScript SimpleWebRTC.
Se você não quiser escrever nenhum código, plataformas comerciais completas de WebRTC estão disponíveis em empresas como vLine, OpenTok e Asterisk.
Para que fique registrado, a Ericsson criou um servidor de sinalização usando PHP no Apache nos primeiros dias do WebRTC. Isso agora está um pouco obsoleto, mas vale a pena analisar o código se você estiver considerando algo semelhante.
Segurança do sinal
A criptografia é obrigatória para todos os componentes do WebRTC.
No entanto, os mecanismos de sinalização não são definidos pelos padrões do WebRTC. Portanto, cabe a você garantir a segurança da sinalização. Se um invasor conseguir sequestrar a sinalização, ele poderá interromper sessões, redirecionar conexões e gravar, alterar ou injetar conteúdo.
O fator mais importante para proteger a sinalização é usar protocolos seguros: HTTPS e WSS, como TLS. Isso garante que as mensagens não possam ser interceptadas sem criptografia. Além disso, tome cuidado para não transmitir mensagens de sinalização de modo que elas possam ser acessadas por outros autores de chamada usando o mesmo servidor de sinalização.
Lidar com NATs e firewalls
Para sinalização de metadados, os apps WebRTC usam um servidor intermediário, mas para streaming de mídia e dados reais, depois que uma sessão é estabelecida, o RTCPeerConnection tenta conectar os clientes diretamente ou ponto a ponto.
Em um mundo mais simples, cada endpoint do WebRTC teria um endereço exclusivo que poderia ser trocado com outros pares para se comunicar diretamente.
Na realidade, a maioria dos dispositivos fica atrás de uma ou mais camadas de NAT, alguns têm software antivírus que bloqueia determinadas portas e protocolos, e muitos estão atrás de proxies e firewalls corporativos. Um firewall e uma NAT podem ser implementados pelo mesmo dispositivo, como um roteador Wi-Fi doméstico.
Os apps WebRTC podem usar o framework ICE
para superar as complexidades das redes do mundo real. Para ativar esse recurso,
seu app precisa transmitir URLs de servidor ICE para RTCPeerConnection.
O ICE tenta encontrar o melhor caminho para conectar os pares. Ele testa todas as possibilidades em paralelo e escolhe a opção mais eficiente que funciona. O ICE primeiro tenta fazer uma conexão usando o endereço do host obtido do sistema operacional e da placa de rede de um dispositivo. Se isso falhar (o que acontecerá com dispositivos atrás de NATs), o ICE vai receber um endereço externo usando um servidor STUN e, se isso falhar, o tráfego será roteado por um servidor de redirecionamento TURN.
Em outras palavras, um servidor STUN é usado para receber um endereço de rede externo, e os servidores TURN são usados para retransmitir o tráfego se a conexão direta (ponto a ponto) falhar.
Todo servidor TURN é compatível com STUN. Um servidor TURN é um servidor STUN com funcionalidade de retransmissão integrada. O ICE também lida com as complexidades das configurações de NAT. Na realidade, o NAT hole punching pode exigir mais do que apenas um endereço IP:porta público.
Os URLs dos servidores STUN e TURN são (opcionalmente) especificados por um app WebRTC no objeto de configuração iceServers, que é o primeiro argumento do construtor RTCPeerConnection. Para appr.tc, esse valor
é assim:
{
'iceServers': [
{
'urls': 'stun:stun.l.google.com:19302'
},
{
'urls': 'turn:192.158.29.39:3478?transport=udp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
},
{
'urls': 'turn:192.158.29.39:3478?transport=tcp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
}
]
}
Depois que o RTCPeerConnection tiver essas informações, a mágica do ICE vai acontecer
automaticamente. O RTCPeerConnection usa o framework ICE para descobrir o melhor
caminho entre os pares, trabalhando com servidores STUN e TURN conforme necessário.
STUN
Os NATs fornecem a um dispositivo um endereço IP para uso em uma rede local privada, mas esse endereço não pode ser usado externamente. Sem um endereço público, não há como os pares do WebRTC se comunicarem. Para contornar esse problema, o WebRTC usa o STUN.
Os servidores STUN estão na Internet pública e têm uma tarefa: verificar o endereço IP:porta de uma solicitação recebida (de um app em execução atrás de um NAT) e enviar esse endereço de volta como resposta. Em outras palavras, o app usa um servidor STUN para descobrir o IP:porta de uma perspectiva pública. Esse processo permite que um par do WebRTC consiga um endereço acessível publicamente para si mesmo e o transmita para outro par por um mecanismo de sinalização para configurar um link direto.
Os servidores STUN não precisam fazer ou lembrar de muita coisa, então servidores STUN com especificações relativamente baixas podem lidar com um grande número de solicitações.
A maioria das chamadas do WebRTC faz uma conexão usando STUN, mas pode ser menor para chamadas entre pares por trás de firewalls e configurações de NAT complexas.
TURN
O RTCPeerConnection tenta configurar a comunicação direta entre os pares por UDP.
Se isso falhar, o RTCPeerConnection vai recorrer ao TCP. Se isso falhar, os servidores TURN
podem ser usados como substitutos, transmitindo dados entre endpoints.
Para reiterar, o TURN é usado para retransmitir streaming de áudio, vídeo e dados entre pares, não para sinalizar dados.
Os servidores TURN têm endereços públicos, então podem ser contatados por pares, mesmo que eles estejam atrás de firewalls ou proxies. Os servidores TURN têm uma tarefa: retransmitir um stream. Ao contrário dos servidores STUN, eles consomem muita largura de banda.
Este diagrama mostra o TURN em ação. O STUN puro não funcionou, então cada par recorre ao uso de um servidor TURN.
Como implantar servidores STUN e TURN
Para testes, o Google executa um servidor STUN público, stun.l.google.com:19302, conforme
usado por appr.tc. Para um serviço STUN/TURN de produção, use o
rfc5766-turn-server. O código-fonte dos servidores STUN e TURN está disponível no
GitHub, onde você também pode
encontrar links para várias fontes de informações sobre a instalação do servidor. Uma
imagem de VM para Amazon Web Services também está disponível.
Uma alternativa de servidor TURN é o restund, disponível como código-fonte e também para a AWS. É possível configurar um restund no Compute :
- Abra o firewall conforme necessário para tcp=443, udp/tcp=3478.
- Crie quatro instâncias, uma para cada IP público, com a imagem padrão do Ubuntu 12.06.
- Defina a configuração do firewall local (permitir QUALQUER de QUALQUER).
- Instale as ferramentas:
shell sudo apt-get install make sudo apt-get install gcc - Instale o libre em creytiv.com/re.html.
- Busque o restund em creytiv.com/restund.html e descompacte.
wgethancke.name/restund-auth.patch e aplique compatch -p1 < restund-auth.patch.- Execute
make,sudo make installpara libre e restund. - Adapte
restund.confàs suas necessidades (substitua os endereços IP e verifique se ele contém a mesma chave secreta compartilhada) e copie para/etc. - Copie
restund/etc/restundpara/etc/init.d/. - Configure o restund:
- Defina
LD_LIBRARY_PATH. - Copie
restund.confpara/etc/restund.conf. - Defina
restund.confpara usar os 10 caracteres à direita. sem precisar de endereço IP externo.
- Defina
- Executar restund
- Teste usando o cliente stund da máquina remota:
./client IP:port
WebRTC para várias partes
Você também pode dar uma olhada no padrão IETF proposto por Justin Uberti para uma API REST para acesso aos serviços TURN.
Há vários casos de uso para streaming de mídia que vão além de uma chamada individual. Por exemplo, uma videoconferência entre um grupo de colegas ou um evento público com um palestrante e centenas ou milhões de espectadores.
Um app WebRTC pode usar várias RTCPeerConnections para que cada endpoint se conecte a todos os outros endpoints em uma configuração de malha. Essa é a abordagem adotada por apps como o talky.io, que funciona muito bem para um pequeno grupo de usuários. Além disso, o consumo de processamento e largura de banda se torna excessivo, especialmente para clientes móveis.
Como alternativa, um app WebRTC pode escolher um endpoint para distribuir streams para todos os outros em uma configuração em estrela. Também é possível executar um endpoint WebRTC em um servidor e criar seu próprio mecanismo de redistribuição (um app cliente de exemplo é fornecido pelo webrtc.org).
Um MediaStream de um RTCPeerConnection pode ser usado como entrada para
outro. Isso permite arquiteturas mais flexíveis, porque permite que um app da Web
processe o roteamento de chamadas escolhendo a qual outro par se conectar. Para ver
isso em ação, consulte Retransmissão de conexão de peering de amostras do WebRTC
e Várias conexões de peering de amostras do WebRTC.
Unidade de controle multiponto
Uma opção melhor para um grande número de endpoints é usar uma unidade de controle multiponto (MCU, na sigla em inglês). Esse é um servidor que funciona como uma ponte para distribuir mídia entre um grande número de participantes. As MCUs podem lidar com diferentes resoluções, codecs e frame rates em uma videoconferência, processar transcodificação, fazer encaminhamento seletivo de stream e mixar ou gravar áudio e vídeo. Para chamadas com várias partes, há uma série de problemas a serem considerados, principalmente como exibir várias entradas de vídeo e mixar áudio de várias fontes. Plataformas de nuvem, como vLine, também tentam otimizar o roteamento de tráfego.
É possível comprar um pacote completo de hardware de MCU ou criar o seu próprio.
Há várias opções de software de MCU de código aberto disponíveis. Por exemplo, o Licode (anteriormente conhecido como Lynckia) produz uma MCU de código aberto para o WebRTC. O OpenTok tem o Mantis.
Além dos navegadores: VoIP, telefones e mensagens
A natureza padronizada do WebRTC possibilita estabelecer comunicação entre um app WebRTC em execução em um navegador e um dispositivo ou plataforma em execução em outra plataforma de comunicação, como um telefone ou um sistema de videoconferência.
O SIP é um protocolo de sinalização usado por sistemas de VoIP e videoconferência. Para permitir a comunicação entre um app da Web WebRTC e um cliente SIP, como um sistema de videoconferência, o WebRTC precisa de um servidor proxy para mediar a sinalização. A sinalização precisa fluir pelo gateway, mas, depois que a comunicação é estabelecida, o tráfego SRTP (vídeo e áudio) pode fluir de peering para peering.
A rede pública de telefonia comutada (PSTN) é a rede de comutação de circuitos de todos os telefones analógicos "antigos". Para chamadas entre apps da Web WebRTC e telefones, o tráfego precisa passar por um gateway PSTN. Da mesma forma, os apps da Web do WebRTC precisam de um servidor XMPP intermediário para se comunicar com endpoints Jingle, como clientes de mensagem instantânea. O Jingle foi desenvolvido pelo Google como uma extensão do XMPP para permitir voz e vídeo em serviços de mensagens. As implementações atuais do WebRTC são baseadas na biblioteca libjingle em C++, uma implementação do Jingle desenvolvida inicialmente para o Talk.
Vários apps, bibliotecas e plataformas usam a capacidade do WebRTC de se comunicar com o mundo externo. Exemplo:
- jsSIP: biblioteca SIP de JavaScript
- Phono: API de telefone JavaScript de código aberto criada como um plug-in
- Twilio: voz e mensagens
Saiba mais
- Leia a documentação da API WebRTC.
- O codelab do WebRTC fornece instruções detalhadas sobre como criar um app de chat de vídeo e texto usando um serviço de sinalização Socket.io em execução no Node.
- Apresentação de Chris Wilson no SFHTML5: Introdução aos apps WebRTC
O livro de 350 páginas WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web fornece muitos detalhes sobre dados e caminhos de sinalização e inclui vários diagramas detalhados de topologia de rede.