Arquitetura
WebRTC
Arquitetura WebRTC do stCall - SIP.js, PJSIP e fluxo de mídia.
Arquitetura WebRTC
O stCall usa WebRTC para chamadas de áudio diretamente no navegador, com SIP.js como biblioteca SIP e Asterisk PJSIP como servidor de mídia.
Stack WebRTC
Navegador (SIP.js)
│
│ SIP sobre WSS (:8089)
▼
Asterisk PJSIP
│
│ SIP Trunk / PSTN
▼
Rede Telefônica
- Codec: Opus (principal), ulaw, alaw
- Latência típica: < 100ms (geralmente < 50ms)
- Largura de banda: ~30-50 kbps por chamada (Opus)
- Setup time: < 2 segundos
Composable: useWebRTCPhone
O composable principal para WebRTC está em composables/webrtc/useWebRTCPhone.ts.
Registro
const phone = useWebRTCPhone()
await phone.register({
wsServer: 'wss://dominio.com:8089/ws',
domain: 'dominio.com',
username: 'agent-1001',
password: 'senha',
displayName: 'João Silva',
})
O registro:
- Cria um
UserAgentdo SIP.js - Conecta via WSS ao Asterisk
- Cria um
Registerercom expiração de 5 minutos - Envia REGISTER para o endpoint PJSIP
Fazer Chamada
await phone.call('1002')
Fluxo:
- Cria um
Inviter(sessão de saída) - Configura constraints de áudio (
{ audio: true, video: false }) - Envia SIP INVITE para
sip:1002@dominio - Monitora mudanças de estado da sessão
Receber Chamada
Chamadas entrantes são tratadas pelo delegate onInvite:
// Internamente no useWebRTCPhone
delegate: {
onInvite: handleIncomingCall,
}
O handler:
- Armazena a sessão (Invitation)
- Extrai número do chamador dos headers SIP
- Atualiza
callStatecom estadoringing - Frontend exibe diálogo de chamada entrante
Atender / Rejeitar
await phone.answer() // Aceita com constraints de áudio
await phone.reject() // Rejeita a chamada
Controles
phone.hangup() // Encerrar chamada (SIP BYE)
phone.hold(true) // Colocar em espera
phone.hold(false) // Retomar
phone.mute(true) // Silenciar microfone
phone.mute(false) // Ativar microfone
phone.sendDTMF('5') // Enviar tom DTMF
Estados da Sessão
O SIP.js emite eventos de mudança de estado:
| Estado | Significado |
|---|---|
Establishing | Chamada sendo estabelecida (ringing) |
Established | Chamada ativa, mídia conectada |
Terminated | Chamada encerrada |
Fluxo de Mídia
Quando a chamada é estabelecida:
RTCPeerConnectioné criado pelo SIP.js- Stream local (microfone) é capturado
- Stream remoto é recebido via RTP
- Streams são expostos via
localStreameremoteStream - Componente
WebRTCAudioPlayerreproduz o áudio remoto
<!-- Reprodutor de áudio invisível -->
<WebRTCAudioPlayer :stream="phone.remoteStream.value" />
ICE e NAT Traversal
Configuração dos servidores ICE:
peerConnectionConfiguration: {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{
urls: 'turn:turn.dominio.com:3478',
username: 'user',
credential: 'pass',
}
]
}
- STUN resolve IPs públicos para NAT simétrico
- TURN é necessário quando STUN falha (NAT restritivo)
Composable: useWebRTCIntegration
Ponte entre WebRTC e eventos ARI (composables/webrtc/useWebRTCIntegration.ts):
- Observa mudanças no estado da chamada WebRTC e sincroniza com o
callStore - Observa eventos ARI e sincroniza com o WebRTC (ex: hangup remoto)
- Expõe
isIntegrated(WebRTC registrado + WebSocket conectado)
Outros Composables WebRTC
| Composable | Arquivo | Responsabilidade |
|---|---|---|
useWebRTCCall | webrtc/useWebRTCCall.ts | Controle individual de chamada |
useWebRTCMedia | webrtc/useWebRTCMedia.ts | Gerenciamento de streams |
useWebRTCSession | webrtc/useWebRTCSession.ts | Sessão SIP |
useWebRTCState | webrtc/useWebRTCState.ts | Estado reativo do WebRTC |
Troubleshooting WebRTC
Sem áudio após conexão
- Verificar permissões de microfone no navegador
- Verificar se
remoteStreamestá anexado ao elemento<audio> - Verificar logs do Asterisk para erros de negociação de mídia
Chamada falha imediatamente
- Verificar credenciais PJSIP
- Confirmar que WSS está ativo (não WS)
- Verificar se o firewall permite portas UDP (RTP)
Áudio unidirecional
- Verificar configuração NAT/firewall
- Confirmar servidor TURN configurado para NAT simétrico
- Verificar se range de portas RTP está aberto
Registro falha
- Verificar transporte WSS do Asterisk:
pjsip show transports - Verificar certificado SSL
- Verificar endpoint:
pjsip show endpoints