diff --git a/src/HotAvalonia.Remote/Program.cs b/src/HotAvalonia.Remote/Program.cs index 7001d0a..e23376d 100644 --- a/src/HotAvalonia.Remote/Program.cs +++ b/src/HotAvalonia.Remote/Program.cs @@ -35,7 +35,7 @@ internal static async Task Main(string[] args) /// true if the application ran successfully; otherwise, false. public static async Task RunAsync(string[] args, CancellationToken cancellationToken) { - if (!ProcessArguments(args, out RemoteFileSystem? remoteFileSystem)) + if (!ProcessArguments(args, out RemoteFileSystem? remoteFileSystem, out int timeout)) { Error(); Error(Help); @@ -47,6 +47,10 @@ public static async Task RunAsync(string[] args, CancellationToken cancell try { + using CancellationTokenSource? cancellationTokenSource = timeout > 0 ? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken) : null; + using Timer? timer = timeout > 0 ? new(_ => (remoteFileSystem.ClientCount == 0 ? cancellationTokenSource : null)?.Cancel(), null, timeout, timeout) : null; + cancellationToken = cancellationTokenSource?.Token ?? cancellationToken; + using RemoteFileSystem fileSystem = remoteFileSystem; await fileSystem.RunAsync(cancellationToken); return true; @@ -162,6 +166,13 @@ A positive value limits the number of file paths returned. A value of 0 or less indicates no limit. Default: 0. + -t, --timeout + Specifies the timeout duration in milliseconds before the server shuts down + if no clients have connected during the provided time frame. + A positive value sets the timeout period. + A value of 0 or less indicates no timeout. + Default: 0. + --allow-shutdown-requests When specified, allows the server to accept shutdown requests from clients. """; @@ -196,13 +207,19 @@ private static bool Error(string? message = null) /// When this method returns, contains the configured instance if the parsing succeeded; /// otherwise, null. /// + /// + /// When this method returns, contains the timeout duration in milliseconds before the server + /// should shut down if no clients have connected during the specified time frame. + /// /// /// true if the arguments were successfully processed and a instance was created; /// otherwise, false. /// - private static bool ProcessArguments(ReadOnlySpan args, out RemoteFileSystem? remoteFileSystem) + private static bool ProcessArguments(ReadOnlySpan args, out RemoteFileSystem? remoteFileSystem, out int timeout) { + timeout = 0; remoteFileSystem = null; + string root = DefaultRoot; byte[]? secret = null; IPEndPoint? endpoint = DefaultEndpoint; @@ -283,6 +300,14 @@ private static bool ProcessArguments(ReadOnlySpan args, out RemoteFileSy args = args.Slice(1); break; + case "-t" when args.Length >= 2: + case "--timeout" when args.Length >= 2: + if (!int.TryParse(args[1], out timeout)) + return Error("Invalid timeout provided. Must be a valid integer."); + + args = args.Slice(1); + break; + case "--allow-shutdown-requests": allowShutdownRequests = true; break;