Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Voneo, the P2P video chat app

Building Voneo, the P2P video chat app

I built a peer-to-peer video chat web app to learn how low-level networking and connection negotiation actually work.
This talk covers the good, the bad, and the lessons learned - from concept to deployment.

Stephen is a Full Stack Software Engineer and Freelancer building practical cloud-based AI solutions.
He loves experimenting with the latest tech and helping teach others along the way! Stephen also helps organise and run the Leeds Mobile meetup

Avatar for Leeds Mobile

Leeds Mobile

October 25, 2026

More Decks by Leeds Mobile

Other Decks in Programming

Transcript

  1. LEEDS MOBILE · SHIPATON SHOWCASE How do two phones actually

    find each other? Building a peer-to-peer video chat app, and what I got wrong along the way Stephen Ingham · Full Stack Software Engineer/Freelancer
  2. THE APP Voneo: peer-to-peer video and text chat 01 Started

    as a John Crickett Coding Challenge 02 Web version: WebRTC and WebSockets written by hand. No Socket.IO, no AI. 03 Shipaton: rebuilt in React Native for Android 02
  3. HOW A CALL CONNECTS Three problems to solve Signalling server

    passes notes, never video Phone A Router Router Phone B video flows direct 03 01 02 03 Find each other Agree how to talk Get through routers A signalling server passes notes An offer and an answer: a spec ICE candidates: every route you between them. sheet each way. might be reachable on.
  4. HOW A CALL CONNECTS Three kinds of ICE candidate LOCAL

    STUN TURN Local address Public address Relay address Your private address. Works if Ask a STUN server: "What do I The fallback when routers you're both on the same Wi-Fi. look like from outside?" won't let direct traffic through. direct direct relayed via server Swap lists through the signalling server → try the pairs → pick the best one that works. 04
  5. How Voneo connects a call One WebSocket server per call,

    in its own Docker container coturn Person A Signalling server 1 · A joins 2 · B joins 3 · offer (newest joiner) 4 · answer 5 · ICE candidates 6 · STUN / TURN 7 · video, direct 8 · chat (via server) Person B
  6. LESSON 1 The bugs were in the boring bits My

    first calls failed on the same network: the easiest possible case. 07 01 02 Candidates never handed over A field name that didn't match Each phone had a list of routes to try. The other No error, no crash. Just a call that silently never phone never saw it. connected.
  7. sent useremail expected UserEmail Your messages are your API. Share

    types, validate, and log every signalling message on both sides. 08
  8. LESSON 2 Browsers won't give you the camera over HTTP

    Laptop on localhost Phone over plain HTTP ngrok HTTPS tunnel A secure context, so the Loaded from my laptop's Worked, right up until I hit the camera works. address. Camera blocked. usage quota. Sort out testing early. "Free" infrastructure costs you time instead of money. 09
  9. LESSON 3 Some design calls I'd keep, some I'd change

    KEEP CHANGE The newest joiner always sends the offer A WebSocket server per call → one server with rooms If both sides offer at once you get "glare". One rule Simpler to run, cheaper, easier to deploy. about who speaks first avoids it entirely. Chat via WebSocket → WebRTC data channel Messages peer to peer, like the video. 10
  10. LESSON 4 Learn it by hand, then let AI speed

    you up BY HAND CLAUDE CODE Web WebRTC and WebSockets Port to react-native-webrtc Slowly and painfully but Almost the same API as the learning the essentials web. Because I understood the core, I could review what the AI produced and spot when it was wrong. 11
  11. EFFICIENCY So how do you make it efficient? DIRECT VS

    RELAYED ONE-TO-ONE VS GROUP Every TURN call sends its video through your server minutes relayed, not with users. Work that out 4 before you set pricing. that forwards one stream from each person. My You pay for that bandwidth. Costs grow with uploads from every phone in a 5-person call Bad for battery and data. Group apps add a server next thing to learn. 12
  12. SHIPATON Why React Native, not a web wrapper Capacitor: web

    app in a native shell React Native + react-native-webrtc Camera needs the native onPermissionRequest Reliable, near-identical API to web WebRTC, and hook. No maintained plugin handles it; requested in works with the signalling server I'd already built. 2020, never built. Touching device hardware? Check the permissions story before you pick an approach. 13
  13. WRAPPING UP Three Points to Take Home: 1 A video

    call is three problems: find each other, agree how to talk, get through the routers. 2 The bugs are in the plumbing. Type and log your signalling messages. 3 Build it by hand once, then use AI to go faster. [QR code]
  14. Thank you for Listening! Add me on Linkedin! Code on

    GitHub https://www.linkedin.com/in/stephen-ingham/ https://github.com/stephen-ingham/ p2p-video-chat-web-app