Language: English | 中文文档
PeerPigeon is a lightweight WebSocket signaling and peer discovery server, with optional hub-to-hub bootstrap for cross-network peer awareness.
- WebSocket endpoint for peer registration and signaling
- Simple HTTP endpoints for health and runtime stats
- Peer discovery broadcasts within a network namespace
- Optional hub mode with bootstrap connections to other hubs
- Minimal, dependency-light Go implementation
- Go 1.21+ recommended
go mod tidy
PORT=3000 HOST=localhost go run ./cmd/peerpigeoncurl http://localhost:3000/health
curl http://localhost:3000/stats
curl http://localhost:3000/hubstats
curl http://localhost:3000/hubsEnvironment variables read at startup:
PORT(default3000): TCP port to listen onHOST(defaultlocalhost): bind hostMAX_CONNECTIONS(default1000): max concurrent WS connectionsCORS_ORIGIN(default*): CORS allow origin for HTTP endpointsIS_HUB(defaultfalse): enable hub mode (generates a hub peer ID)HUB_MESH_NAMESPACE(defaultpigeonhub-mesh): namespace used for hubsBOOTSTRAP_HUBS(default empty): comma-separated WebSocket URLs of other hubs (used whenIS_HUB=true)AUTH_TOKEN(default empty): if set, WS clients must provide a bearer token
Example:
PORT=3001 HOST=0.0.0.0 IS_HUB=true BOOTSTRAP_HUBS="ws://other-host:3000/ws" \
go run ./cmd/peerpigeon- URL:
ws://<host>:<port>/ws?peerId=<40-hex> - The
peerIdmust be a 40-character hex string.
If AUTH_TOKEN is set, clients must include either:
- Header:
Authorization: Bearer <token> - Query:
?token=<token>
After connecting, send an announce message:
{
"type": "announce",
"networkName": "global",
"data": { "isHub": false }
}Responses include peer-discovered messages for existing peers in the same networkName.
Used to exchange WebRTC-like payloads between peers:
offer,answer,ice-candidate
Example:
{
"type": "offer",
"targetPeerId": "<peer-id>",
"networkName": "global",
"data": { "sdp": "..." }
}Send {"type":"ping"} and receive {"type":"pong"} with a timestamp.
GET /health: health status and basic metricsGET /stats: runtime statistics (connections, peers, hubs, etc.)GET /hubstats: bootstrap and hub connectivity detailsGET /hubs: list of registered hub peers
- The server initializes a Gin engine and registers HTTP routes.
- A cleanup ticker performs periodic maintenance and relay dedup cleanup.
- If hub mode is enabled and
BOOTSTRAP_HUBSis set, it connects to remote hubs.
Key code paths:
- Startup and routes:
internal/server/server.go:56-94 - Cleanup ticker:
internal/server/server.go:79-85,internal/server/server.go:455-472 - Port probing:
internal/server/server.go:105-115
GET /wsupgrades to WebSocket.- If
AUTH_TOKENis set, clients must provideAuthorization: Bearerortokenquery param. - Connections are tracked in memory; peers are recorded with metadata.
Key code paths:
- Handshake and auth:
internal/server/server.go:117-158 - Peer record updates:
internal/server/server.go:171-197
announceassigns the peer to a network namespace and (optionally) marks it as a hub.- Newly announced peers are broadcast to others via
peer-discovered. - A new peer receives currently active peers in its network.
Key code paths:
- Announce:
internal/server/server.go:199-231 - Register hub:
internal/server/server.go:233-237 - Broadcast discovery:
internal/server/server.go:239-247 - Send existing peers to new:
internal/server/server.go:249-258
- If the target is locally connected and in the same network, messages are forwarded directly.
- Otherwise, messages are relayed via bootstrap hubs (if available) with deduplication.
Key code paths:
- Local forward:
internal/server/server.go:402-405 - Signaling handler:
internal/server/server.go:281-309 - Relay dedup hash:
internal/server/util.go:33-37
- In hub mode, the server generates a hub peer ID and optionally dials configured
BOOTSTRAP_HUBS. - On bootstrap open, the hub announces capabilities and local peers.
- Incoming
peer-discoveredfrom remote hubs is cached and forwarded to local peers.
Key code paths:
- Connect to bootstrap hubs:
internal/server/hubs.go:26-54 - Announce to bootstrap and local peers:
internal/server/hubs.go:98-136 - Handle bootstrap messages:
internal/server/hubs.go:138-167 - Cache cross-hub peers:
internal/server/server.go:446-453 - Forward to local peers:
internal/server/server.go:438-444
go test ./...- Slow dependency downloads: set a Go module proxy
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,https://goproxy.cn,https://goproxy.io,https://proxy.golang.org,direct- Port conflicts: the server probes for an available port up to
MaxPortRetries. - Invalid
peerId: must be a 40-character hex string.
From the legendary developer Daniel Raeder https://github.com/PeerPigeon/PeerPigeon