package main import ( "embed" "flag" "fmt" "io/fs" "log" "net/http" "time" "github.com/gorilla/websocket" ) //go:embed webui/* var webUI embed.FS var wsUpgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } func runServe(portName string, baud int, args []string) error { serveFlags := flag.NewFlagSet("serve", flag.ExitOnError) addr := serveFlags.String("addr", ":8080", "dashboard HTTP listen address") apiAddr := serveFlags.String("api-addr", ":8081", "external API HTTP listen address (empty to disable)") accelInterval := serveFlags.Duration("accel-interval", defaultAccelStreamInterval, "accel WebSocket sample period on API server") interval := serveFlags.Duration("interval", 2*time.Second, "UART poll interval") if err := serveFlags.Parse(args); err != nil { return err } if portName == "" { return fmt.Errorf("serve requires -port (master UART)") } link := newManagedSerial(portName, baud) link.quiet = true defer link.Close() hub := newWSHub() streamCtl := newAccelStreamCtl() stop := make(chan struct{}) defer close(stop) go runPoller(link, portName, hub, streamCtl, *interval, stop) go runBatteryPoller(link, hub, 5*time.Second, stop) go runAccelDashboardPoller(link, hub, *accelInterval, stop) var apiSrv *http.Server if *apiAddr != "" { apiSrv = runAPIServer(portName, link, *apiAddr, *accelInterval, hub, streamCtl, stop) defer shutdownAPIServer(apiSrv) } mux := http.NewServeMux() mountServeAPI(mux, link, hub, streamCtl) mux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { conn, err := wsUpgrader.Upgrade(w, r, nil) if err != nil { log.Printf("websocket upgrade: %v", err) return } hub.register(conn) defer hub.unregister(conn) defer conn.Close() for { if _, _, err := conn.ReadMessage(); err != nil { return } } }) ui, err := fs.Sub(webUI, "webui") if err != nil { return err } mux.Handle("/", http.FileServer(http.FS(ui))) log.Printf("dashboard http://localhost%s (UART %s @ %d baud, poll %s, accel %s, auto-reconnect)", *addr, portName, baud, interval.String(), accelInterval.String()) if *apiAddr == "" { log.Printf("external API disabled (-api-addr \"\")") } return http.ListenAndServe(*addr, mux) }