12/04/2026 18:16pm

EP.116 Real-time Voice/Video Communication with WebRTC + WebSocket Signaling in Go
#Golang
#Go
#Video Call
#Voice Chat
#WebSocket
#WebSocket Signaling
#WebRTC
Text-based chat over WebSocket is just the beginning. Modern communication systems must support real-time voice and video features just like your favorite meeting apps.
And the global standard for real-time media transmission is WebRTC. But here’s the catch: WebRTC cannot initiate the connection by itself. It needs a mechanism called Signaling, and in this tutorial, we’ll use WebSocket as our signaling server.
This article will walk you through everything you need to know: From PeerConnection → ICE Candidates → Signaling → actual audio/video streaming all with real, production-grade Go code.
🔊 What is WebRTC?
WebRTC is a framework for real-time peer-to-peer communication directly between browsers.
✨ Key features:
- Low-latency audio/video (less than 100ms)
- True peer-to-peer connection (no central server for media)
- Secure by default (encrypted media streams)
🤔 What about WebSocket?
| Feature | WebSocket | WebRTC |
|---|---|---|
| Real-time messaging | ✅ | ✅ |
| File transfer | ✅ | ✅ |
| Audio/Video streaming | ❌ Not ideal | ✅ |
| Peer-to-peer connection | ❌ | ✅ |
| Sub-50ms latency | ❌ | ✅ |
WebRTC is purpose-built for real-time media transmission.
🛰 Components of WebRTC
- RTCPeerConnection
Handles encrypted media connection between peers. - ICE Candidate
Determines possible network paths (LAN, Public IP, TURN server, etc.) - SDP (Session Description Protocol)
Describes media details (codec, bitrate, etc.) - Signaling Server
Responsible for exchanging messages like offer, answer, and ICE candidates between clients.
⚠️ WebRTC does not include signaling you need to implement it yourself.
🔄 Using WebSocket as Signaling Server
Connection flow:
- 👤 Client A creates an
offerand sends it via WebSocket - 🔁 Server forwards the offer to Client B
- 👤 Client B replies with an
answer - 🔄 Both clients exchange ICE candidates
- ✅ Once handshake is complete → media streaming begins!
🧪 Go Example: WebSocket Signaling Server
type SignalMessage struct {
Type string `json:"type"` // offer, answer, ice
From string `json:"from"`
To string `json:"to"`
Data json.RawMessage `json:"data"`
}
var clients = make(map[string]*websocket.Conn)
func signalingHandler(c *fiber.Ctx) error {
conn, err := upgrader.Upgrade(c.Context(), nil)
if err != nil { return err }
clientID := c.Query("id")
clients[clientID] = conn
for {
_, msg, err := conn.ReadMessage()
if err != nil {
delete(clients, clientID)
return nil
}
var signal SignalMessage
json.Unmarshal(msg, &signal)
if target, ok := clients[signal.To]; ok {
target.WriteMessage(websocket.TextMessage, msg)
}
}
}
🎧 Client-side Code (JavaScript)
1. Create PeerConnection
const pc = new RTCPeerConnection({
iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
});
pc.onicecandidate = event => {
if (event.candidate) {
socket.send(JSON.stringify({
type: "ice",
to: remoteUser,
data: event.candidate
}));
}
};
2. Start Call and Send Offer
async function startCall() {
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
stream.getTracks().forEach(track => pc.addTrack(track, stream));
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
socket.send(JSON.stringify({
type: "offer",
to: remoteUser,
data: offer
}));
}
🔐 Using TURN Server (When P2P Fails)
In some scenarios, P2P connection might fail due to:
- NAT restrictions
- Firewalls blocking ports
- Mobile networks
In such cases, you’ll need a TURN server to relay the media Examples:
- Coturn
- Twilio TURN Service
- Google Cloud WebRTC Infra
⚙️ Production-grade Best Practices
| Security Concern | Recommended Strategy |
|---|---|
| Token Reuse Prevention | Use JWT with Device Binding |
| Stranger Calls | Use Room-based Permission |
| DDOS / Abuse | Implement Rate Limits |
| Media Relay | Use Secure TURN (with auth) |
🚀 Challenge: Build Your First Video Call
✅ Implement a working prototype using:
- WebSocket → Signaling
- WebRTC → P2P connection
- ICE Candidates exchange
- Media streaming
Start with 1-on-1 calls → Expand to group call later!
🔮 Coming Up Next: WebSocket for IoT Device Networks
In the next episode, we’ll explore building a real-time IoT network with WebSocket:
- Manage thousands of devices (sensors, robots, smart home)
- Handle device auth & secure communication
- Optimize bandwidth for constrained networks
If you’ve made it this far you’re ready for real-time engineering at scale! 🎯