
Show HN: WebRTC Nuts and Bolts, A holistic way of understanding how WebRTC runs by adalkiran
A holistic way of understanding how WebRTC and its protocols run in practice, with code and detailed documentation. “The nuts and bolts” (practical side instead of theoretical facts, pure implementation details) of required protocols without using external dependencies or libraries.
When you run the project and follow the instructions, web page initializes the webcam, does handshake with the backend application (executes several WebRTC processes), at the end, the backend catches keyframe images and saves them as JPEG image files. You can see your caught keyframes at /backend/output/ folder as shoot1.jpg, shoot2.jpg etc… if multiple keyframes were caught.
You can track which steps taken during this journey by debugging or tracking the output at console.
WHY THIS PROJECT?
This project was initially started to learn Go language and was made for experimental and educational purposes only, not for production use.
After some progress on the development, I decided to pivot my experimental work to a walkthrough document. Because although there are lots of resources that exist already on the Internet, they cover small chunks of WebRTC concepts or protocols atomically. And they use the standard way of inductive method which teach in pieces then assemble them.
But my style of learning leans on the deductive method instead of others, so instead of learning atomic pieces and concepts first, going linearly from beginning to the end, and learning an atomic piece on the time when learning this piece is required.
DOCUMENTATION
The adventure of a WebRTC stream from start to finish can be found documented as step by step in docs folder
COVERAGE
Web front-end side: Pure TypeScript implementation:
- Communicate with signaling backend WebSocket,
- Gathering webcam streaming track from browser and send this track to backend via UDP.
Server back-end side: Pure Go language implementation:
- A simple signaling back-end WebSocket to transfer SDP (Session Description Protocol) using Gorilla WebSocket library.
- Single port UDP listener, supports demultiplexing different data packet types (STUN, DTLS handshake, SRTP, SRTCP) coming from the same UDP connection.
- Protocol implementations of (only required parts):
- STUN (Session Traversal Utilities for NAT) for discovering external IP behind NAT by a STUN server and replying to the client’s STUN binding request came by UDP connection.
- DTLS (Datagram Transport Layer Security) for secure handshake, authenticating each oter, and crypto key exchange process. DTLS is similar to TLS (Transport Layer Security), DTLS runs over UDP instead of TCP. This project supports only DTLS v1.2.
- RTP (Real-time Transport Protocol) for transferring media packets in fragments.
- SRTP (Secure Real-time Transport Protocol), a secure version of RTP.
- Only header parsing for VP8 video format to depacketizing fragmented packets to construct a video frame. libvpx-go was used for decoding VP8 keyframe as image.
- github.com/fatih/color was used while printing colored output on console while logging.
- Implementation of TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 cipher suite support using Go Cryptography library.
INSTALLATION and RUNNING
This project was designed to run in Docker Container. Docker Compose file creates two containers: webrtcnb-ui and webrtcnb-backend.
Important Note:
First of all, you should learn your machine’s LAN IP address and write it into backend/config.yml file at server/udp/dockerHostIp section.
Because, we didn’t configure the docker networking type as “host”, and the backend application in the container cannot discover the host machine’s (your physical computer) real LAN IP but it needs this information to run correctly. Unfortunately, it can’t run with 127.0.0.1. The LAN IPs usually start with 192 or 10.
Tried to configure the docker networking type as “host”, but it doesn’t work in Docker Desktop for Mac, because of Docker’s subsystem runs in a Linux VM on MacOS, and it always returns 192.168.65.1 as gateway.
You can run it production mode or development mode.
Production Mode
- Clone this repo and run in terminal:
- Wait until Go and Node modules were installed and configured. This can take some time. You can checkout the download status by:
- After waiting for enough time, open a web browser and visit http://localhost:8080 (Tested on Chrome)
Development Mode: VS Code Remote – Containers
To continue with VS Code and if this is your first time to work with Remote Containers in VS Code, you can checkout this link to learn how Remote Containers work in VS Code and follow the installation steps of Remote Development extension pack.
Then, follow these steps:
- Clone this repo to your local filesystem
- Open the folder “webrtc-nuts-and-bolts” with VS Code by “Open Folder…” command. This opens the root folder of the project.
- Press F1 and select “Remote Containers: Open Folder in Container…” then select “backend” folder in “webrtc-nuts-and-bolts”.
- This command creates (if they don’t exist) required containers in Docker, then connects inside of webrtcnb-backend container for development and debugging purposes.
- Wait until the containers created, configured and related VS Code server extensions installed inside the container. This can take some time. VS Code can ask for some required installations, click “Install All” for these prompts.
- After completion of all installations, press F5 to start server application.
- Then, open a web browser and visit http://localhost:8080 (Tested on Chrome)