Add WebRTC support and remove deviceId from apis

This commit is contained in:
x0gp
2026-07-15 00:57:36 +04:00
parent 7a7913d2ee
commit c25e0bc581
11 changed files with 1428 additions and 17 deletions
+27 -10
View File
@@ -196,6 +196,9 @@ func main() {
clansSvc := clans.NewService(clans.NewPgStore(pool))
driversSvc := drivers.NewService(drivers.NewPgStore(pool))
// WebRTC 1-to-1 driver-car proxy service
webrtcSvc := NewWebRTCService(logger, engine, lobbySvc, videoSvc)
// Persist finished races so the /api/races list and keyset pagination
// can serve historical data across restarts. The snapshot is best-
// effort: errors are logged but never block the lobby.
@@ -280,6 +283,9 @@ func main() {
// UDP video and command receiver.
videoSvc.Start(ctx, &wg)
// Start WebRTC service
webrtcSvc.Start(ctx, &wg)
mux := http.NewServeMux()
mux.HandleFunc("/health", healthHandler(hub, engine))
mux.HandleFunc("/api/version", versionHandler())
@@ -301,8 +307,12 @@ func main() {
mux.HandleFunc("/api/drivers/", driversByIDHandler(driversSvc, lobbySvc))
mux.HandleFunc("/api/video/stream", videoSvc.StreamHandler())
mux.HandleFunc("/api/video/control", videoSvc.ControlHandler())
mux.HandleFunc("/api/webrtc/connect", webrtcSvc.ConnectHandler())
mux.HandleFunc("/ws", wsHandler(cfg, engine, hub, cat, lobbySvc, driversSvc, videoSvc, logger))
// Static client files (resolving TODO)
mux.Handle("/", http.FileServer(http.Dir("./web")))
// Swagger UI + OpenAPI spec.
// UI: GET /swagger/index.html
// Spec: GET /swagger/doc.json
@@ -561,7 +571,7 @@ func readPump(cfg *config.Config, c *realtime.Client, conn *websocket.Conn, e *c
case transport.TypeClientHello:
handleClientHello(c, e, cfg, lobbySvc, driversSvc, env)
case transport.TypeJoinRace:
handleJoinRace(c, e, env)
handleJoinRace(c, e, lobbySvc, env)
case transport.TypeLeaveRace:
handleLeaveRace(c, e, env)
case transport.TypeInputState:
@@ -619,7 +629,7 @@ func handleClientHello(c *realtime.Client, e *control.Engine, cfg *config.Config
c.Send <- mustEncode(transport.TypeServerHello, hello)
}
func handleJoinRace(c *realtime.Client, e *control.Engine, env *transport.Envelope) {
func handleJoinRace(c *realtime.Client, e *control.Engine, lobbySvc *lobby.Service, env *transport.Envelope) {
payload, _ := env.Payload.(map[string]any)
slot := 0
name := "anon"
@@ -631,7 +641,18 @@ func handleJoinRace(c *realtime.Client, e *control.Engine, env *transport.Envelo
name = v
}
}
car, err := e.AddCar(c.ID, name, slot)
// Resolve DeviceID for this driver internally
driverID := c.DriverID
if driverID == "" {
driverID = c.ID
}
var deviceID *int
if d, err := lobbySvc.GetDriver(driverID); err == nil {
deviceID = d.DeviceID
}
car, err := e.AddCar(c.ID, name, slot, deviceID)
if err != nil {
sendError(c, "join_failed", err.Error())
return
@@ -666,12 +687,8 @@ func handleInput(c *realtime.Client, e *control.Engine, lobbySvc *lobby.Service,
}
car.ApplyInput(in, 1.0/60.0)
// Forward command transitions to ESP32 physical car if driver is assigned one
driverID := c.DriverID
if driverID == "" {
driverID = c.ID
}
if d, err := lobbySvc.GetDriver(driverID); err == nil && d.DeviceID != nil {
// Forward command transitions to ESP32 physical car if car has a device_id assigned
if car.DeviceID != nil {
var cmd string
if in.Throttle > 0.1 {
cmd = "start"
@@ -686,7 +703,7 @@ func handleInput(c *realtime.Client, e *control.Engine, lobbySvc *lobby.Service,
if cmd != "" && cmd != c.LastUDPCommand {
c.LastUDPCommand = cmd
_ = videoSvc.SendCommand(uint8(*d.DeviceID), cmd)
_ = videoSvc.SendCommand(uint8(*car.DeviceID), cmd)
}
}