package main import ( "flag" "log" "strings" kcp "github.com/xtaci/kcp-go/v5" "omnisocketgo/cmd/internal/latencylog" "omnisocketgo/cmd/internal/server" "omnisocketgo/cmd/internal/transport" ) func main() { listenAddr := flag.String("listen", ":9002", "KCP server listen address") bindDevice := flag.String("bind-device", "", "optional Linux network device used when listening") logPath := flag.String("latency-log", "", "optional JSONL file path for latency timestamp logs") kcpTimestampDebugLogPath := flag.String("kcp-ts-debug-log", "", "optional JSONL file path for KCP packet kernel timestamp debug records") flag.Parse() hubOptions := make([]server.KCPOption, 0, 1) if *logPath != "" { logger, err := latencylog.NewJSONLLogger(*logPath) if err != nil { log.Fatalf("create latency logger %s: %v", *logPath, err) } defer logger.Close() hubOptions = append(hubOptions, server.WithKCPLogger(logger)) } var packetLogger transport.KCPPacketDebugLogger if *kcpTimestampDebugLogPath != "" { logger, err := transport.NewJSONLKCPPacketDebugLogger(*kcpTimestampDebugLogPath) if err != nil { log.Fatalf("create kcp packet debug logger %s: %v", *kcpTimestampDebugLogPath, err) } defer logger.Close() packetLogger = logger } listener, packetConn, err := transport.ListenKCPSessions(*listenAddr, *bindDevice, packetLogger, latencylog.NodeRoleServer, "hub") if err != nil { log.Fatalf("listen kcp on %s: %v", *listenAddr, err) } defer packetConn.Close() defer listener.Close() hub := server.NewKCPHub(hubOptions...) log.Printf("kcp server listening on %s", listener.Addr()) for { session, err := listener.AcceptKCP() if err != nil { if strings.Contains(err.Error(), "closed") { return } log.Printf("accept kcp session: %v", err) continue } go func(sess *kcp.UDPSession) { if serveErr := hub.ServeSession(sess); serveErr != nil { log.Printf("kcp session closed: %v", serveErr) } }(session) } }