using System; using System.IO; using System.Threading; using System.Threading.Tasks; using XWorld.Server.Gateway; namespace XWorld.Server.Cdn.Runner { // 独立内网 CDN(HTTP 静态文件服务)。仿 Gateway.Runner 形态。 // 用法: dotnet run --project Server/Cdn.Runner -- --root <发布产物>/client --port 15081 --lan public static class Program { public static async Task Main(string[] args) { string root = GetArg(args, "--root"); if (string.IsNullOrWhiteSpace(root)) { Console.Error.WriteLine("缺少必填参数 --root <目录>(指向发布产物 client/ 目录,含 minigame///...)"); Environment.ExitCode = 2; return; } root = Path.GetFullPath(root); int port = int.TryParse(GetArg(args, "--port"), out int p) ? p : 15081; bool lan = Array.Exists(args, a => string.Equals(a, "--lan", StringComparison.OrdinalIgnoreCase)); var cdn = new StaticFileServer(root, port, bindAllInterfaces: lan); await cdn.StartAsync(); string advertiseHost = lan ? LanIp.Resolve() : "127.0.0.1"; Console.WriteLine("XWorld CDN static file server started."); Console.WriteLine(" root: " + root); Console.WriteLine(" listen: " + cdn.HttpBaseUrl + (lan ? " (all interfaces)" : " (loopback)")); Console.WriteLine(" advertise cdn root: http://" + advertiseHost + ":" + port + "/ (XWorld// , minigame///)"); Console.WriteLine("Press Ctrl+C to stop."); using var stop = new CancellationTokenSource(); Console.CancelKeyPress += (s, e) => { e.Cancel = true; stop.Cancel(); }; try { await Task.Delay(Timeout.InfiniteTimeSpan, stop.Token); } catch (OperationCanceledException) { } await cdn.StopAsync(); } private static string GetArg(string[] args, string name) { for (int i = 0; i < args.Length - 1; i++) if (string.Equals(args[i], name, StringComparison.OrdinalIgnoreCase)) return args[i + 1]; return null; } } }