safesight-edge/agent/cmd/safesight-agent/main.go
tian c26531b4f3 refactor: rebrand to SafeSight Edge
- Rename Agent binary: rk3588-agent → safesight-agent
- Update Go module: rk3588sys/agent → safesight-agent
- Rename CMake project: rk3588_media_server → safesight_media
- Rename Media binary: media-server → safesight-media
- Update all install paths, scripts, and config references
2026-07-17 11:00:39 +08:00

172 lines
4.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"context"
"flag"
"fmt"
"net"
"net/http"
"net/url"
"os"
"os/signal"
"path/filepath"
"strconv"
"strings"
"sync"
"syscall"
"time"
"safesight-agent/internal/config"
"safesight-agent/internal/discovery"
"safesight-agent/internal/httpapi"
"safesight-agent/internal/log"
"safesight-agent/internal/mediaserver"
"safesight-agent/internal/modelstore"
"safesight-agent/internal/sysinfo"
)
var Version = "0.0.0-dev"
var BuildID = "dev"
var BuildType = "dev"
var GitSHA = ""
func main() {
cfgPath := flag.String("config", "", "config file path")
flag.Parse()
if strings.TrimSpace(*cfgPath) == "" {
log.Error("missing --config")
os.Exit(2)
}
cfg, err := config.Load(*cfgPath)
if err != nil {
log.Error("load config failed: " + err.Error())
os.Exit(2)
}
agentPort, err := portFromListen(cfg.Agent.Listen)
if err != nil {
log.Error("invalid agent.listen: " + err.Error())
os.Exit(2)
}
mediaPort, err := portFromBaseURL(cfg.Agent.MediaServerBaseURL)
if err != nil {
log.Error("invalid agent.media_server_base_url: " + err.Error())
os.Exit(2)
}
deviceID, err := sysinfo.DeviceID(cfg.Agent.DeviceIDPath)
if err != nil {
log.Error("device_id failed: " + err.Error())
os.Exit(2)
}
ms, err := mediaserver.New(cfg.Agent.MediaServerBaseURL, cfg.Agent.MediaServerTimeout, cfg.Agent.MediaServerRetry.MaxAttempts, cfg.Agent.MediaServerRetry.BackoffMS)
if err != nil {
log.Error("media-server client init failed: " + err.Error())
os.Exit(2)
}
store := modelstore.New(cfg.Agent.ModelsDir, cfg.Agent.MaxUploadMB)
baseDir := filepath.Dir(*cfgPath)
if abs, err := filepath.Abs(*cfgPath); err == nil {
baseDir = filepath.Dir(abs)
}
h := httpapi.New(cfg.Agent, baseDir, ms, store, deviceID, agentPort, mediaPort, Version, BuildID, BuildType, GitSHA)
log.Info("rk3588-agent version=" + Version + " build_id=" + BuildID + " build_type=" + BuildType + " git_sha=" + GitSHA)
httpSrv := &http.Server{
Addr: cfg.Agent.Listen,
Handler: h,
ReadHeaderTimeout: 5 * time.Second,
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
log.Info("http listening on " + cfg.Agent.Listen)
if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Error("http server error: " + err.Error())
stop()
}
}()
// 自动启动 media-server如果启用
if cfg.Agent.MediaServerProcess.Enable {
time.Sleep(500 * time.Millisecond) // 等待 HTTP 服务启动
log.Info("auto-starting media-server...")
if err := h.StartMediaServer(""); err != nil {
log.Error("auto-start media-server failed: " + err.Error())
} else {
log.Info("media-server auto-started")
}
}
if cfg.Agent.DiscoveryEnable {
wg.Add(1)
go func() {
defer wg.Done()
resp := &discovery.Responder{
Port: cfg.Agent.DiscoveryPort,
DeviceID: deviceID,
DeviceName: cfg.Agent.DeviceName,
Hostname: sysinfo.Hostname(),
AgentPort: agentPort,
MediaPort: mediaPort,
Version: Version,
BuildID: BuildID,
BuildType: BuildType,
GitSHA: GitSHA,
ConfigPath: cfg.Agent.ConfigPath,
}
log.Info("udp discovery listening on :" + strconv.Itoa(cfg.Agent.DiscoveryPort))
if err := resp.Run(ctx); err != nil {
log.Error("udp discovery error: " + err.Error())
stop()
}
}()
}
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
_ = httpSrv.Shutdown(shutdownCtx)
cancel()
wg.Wait()
}
func portFromListen(listen string) (int, error) {
_, portStr, err := net.SplitHostPort(listen)
if err != nil {
return 0, err
}
p, err := strconv.Atoi(portStr)
if err != nil || p <= 0 || p > 65535 {
return 0, fmt.Errorf("invalid port: %q", portStr)
}
return p, nil
}
func portFromBaseURL(base string) (int, error) {
u, err := url.Parse(base)
if err != nil {
return 0, err
}
if u.Port() != "" {
p, err := strconv.Atoi(u.Port())
if err != nil {
return 0, err
}
return p, nil
}
if u.Scheme == "https" {
return 443, nil
}
return 80, nil
}