Gryt

Overview

Go SFU — WebRTC media forwarding with Pion

The Gryt SFU (Selective Forwarding Unit) is a Go-based WebRTC media server built with Pion WebRTC. It receives audio tracks from each participant and forwards them to every other peer in the room without transcoding.

Features

  • Selective forwarding: Routes audio streams with no transcoding
  • Pion WebRTC: ICE handling, STUN support, connection recovery
  • Thread-safe: Concurrent handling of multiple connections
  • Lightweight: Minimal CPU and memory footprint

Project structure

sfu/
├── cmd/sfu/           # Entry point
├── internal/
│   ├── config/        # Environment-based configuration
│   ├── websocket/     # Thread-safe WebSocket wrapper + handler
│   ├── webrtc/        # Peer connection management
│   ├── track/         # Media track lifecycle
│   └── signaling/     # Offer/answer coordination
└── pkg/types/         # Shared message structures

Getting started

cd packages/sfu
cp env.example .env
go run ./cmd/sfu

Or with the start script:

./start.sh

Environment variables

VariableDefaultDescription
PORT5005HTTP server port
STUN_SERVERSstun:stun.l.google.com:19302Comma-separated STUN servers
ICE_UDP_PORT_MINMin UDP port for WebRTC media
ICE_UDP_PORT_MAXMax UDP port for WebRTC media
ICE_ADVERTISE_IPPublic IP(s) to advertise in ICE candidates (comma-separated for multi-network)
LOG_LEVELinfodebug, info, warn, error
MAX_CONNECTIONS1000Max concurrent connections

WebSocket events

Client to SFU

EventPayloadDescription
joinJoinMessageJoin a room
leaveLeaveMessageLeave room
offerRTCSessionDescriptionWebRTC offer
answerRTCSessionDescriptionWebRTC answer
ice-candidateRTCIceCandidateICE candidate

SFU to Client

EventPayloadDescription
joinedJoinedMessageRoom join confirmation
user-joinedUserJoinedMessagePeer joined
user-leftUserLeftMessagePeer left
offerRTCSessionDescriptionWebRTC offer
answerRTCSessionDescriptionWebRTC answer
ice-candidateRTCIceCandidateICE candidate

Track lifecycle

  1. Client joins room — peer connection created
  2. Client sends offer — SFU processes and creates answer
  3. Client adds audio track — SFU forwards to other peers
  4. Client leaves — tracks and connections cleaned up

Debug endpoints

EndpointDescription
GET /healthHealth check
GET /debug/roomsActive rooms
GET /debug/peersPeer connections
GET /debug/tracksMedia tracks
GET /metricsPrometheus metrics

Development

go mod download
go test ./...
go run -race ./cmd/sfu   # with race detection

On this page