From 3223dbd8f68551dbe60c8387464d43b6052af4da Mon Sep 17 00:00:00 2001 From: SITO Date: Wed, 19 Aug 2026 19:55:40 +0200 Subject: [PATCH] wiki: la llamada entre dos participantes, probada, con captura --- Llamadas.md | 24 +++++++++++++++++++++--- Roadmap.md | 7 ++++--- img/10-llamada-dos.png | Bin 0 -> 23245 bytes 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 img/10-llamada-dos.png diff --git a/Llamadas.md b/Llamadas.md index 6d6ec5a..a2766a4 100644 --- a/Llamadas.md +++ b/Llamadas.md @@ -108,12 +108,30 @@ servidor web. Sin esa línea, tu TURN es una puerta a tus propios servicios. Compruébalo con `turnutils_uclient` contra una IP privada y contra la IP pública del servidor: **las dos deben fallar**. +## Probado entre dos participantes + +![Llamada entre dos participantes](img/10-llamada-dos.png) + +Dos navegadores distintos en la misma sala, cada uno con su cámara. A la derecha, el +vídeo que llega del otro participante, con su reloj corriendo. + +Lo que ocurre por debajo, leído de la señalización de la sala: + +1. Los dos anuncian su presencia (`hello`). +2. Se abre primero un **canal de datos**, y el indicador pasa de *server relay* (punto + gris) a **🔒 P2P (WebRTC)** en verde: desde ahí, los mensajes de la sala van + directos entre navegadores sin tocar el servidor. +3. Al pulsar **Llamar** se renegocia añadiendo `audio` y `video`, y el otro lado + responde. Comprobado en el SDP intercambiado. + +Los participantes se identifican por navegador, no por identidad de SSB: dos +navegadores del mismo nodo también se enlazan entre sí, que es como está hecha esta +prueba. + ## Limitaciones honestas -- **Un participante = un nodo.** Dos pestañas del mismo Oasis comparten identidad y no - se enlazan entre sí. Para probar de verdad hacen falta dos nodos distintos. - **Sin TURN, con datos móviles casi nunca conectará.** El CGNAT de los operadores lo - impide. + impide, y por eso hace falta el TURN del pub. - La señalización pasa por el servidor de la sala: un servidor comprometido podría colocarse en medio. La media va cifrada extremo a extremo, pero **quien controla la señalización controla con quién crees que hablas**. diff --git a/Roadmap.md b/Roadmap.md index 89c33cc..712e062 100644 --- a/Roadmap.md +++ b/Roadmap.md @@ -37,9 +37,10 @@ Sin fechas: esto se hace cuando se puede. **Probado**: arranque con cuenta aislada, crear salas, mensajes, respuesta citada, `/modules`, los cuatro temas, y el panel de llamada en su sitio. -**No probado**: una llamada real entre dos equipos distintos con TURN de por medio. -Lo que está verificado es que el panel se dibuja bien y que el navegador pide los -permisos; la negociación entre dos nodos separados por NAT está pendiente. +**No probado**: una llamada entre dos equipos separados por NAT, con TURN de por +medio. Lo que sí está comprobado es la llamada entre dos participantes en la misma +red, con el vídeo del otro llegando y el SDP negociando audio y vídeo. Ver +[Llamadas](Llamadas). ## Diferencias con la versión para móvil diff --git a/img/10-llamada-dos.png b/img/10-llamada-dos.png new file mode 100644 index 0000000000000000000000000000000000000000..f3cb55e9e79c5292c7f539ba50f22b9a2b074504 GIT binary patch literal 23245 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 n(H