private static async Task ComputationalAsyncCallback(ServerArguments serverArguments, HttpListenerContext context, CancellationToken cancellationToken) { var profiler = Stopwatch.StartNew(); var query = context.Request.QueryString["query"]; if (cancellationToken.IsCancellationRequested) { Log.Warn($"Task [{query}] cancelled before computations."); return; } var responseBytes = await ComputeResponseAsync(serverArguments, query, cancellationToken); await context.Response.OutputStream.WriteAsync(responseBytes, 0, responseBytes.Length, cancellationToken); if (cancellationToken.IsCancellationRequested) { Log.Warn($"Task [{query}] cancelled while or after computing/sending response."); return; } Log.Info($"Request [{query}] processed in {profiler.ElapsedMilliseconds} ms."); }
private static async Task <byte[]> ComputeResponseAsync(ServerArguments serverArguments, string query, CancellationToken cancellationToken) { await Task.Delay(serverArguments.MethodDuration, cancellationToken); return(GetBase64HashBytes(query, Encoding.UTF8)); }
/* Two scenarios: 'query'[+'guid'] or 'cancel' requests. */ private static Func <HttpListenerContext, Task> CreateAsyncCallback(ServerArguments serverArguments) { return(async context => { var queryString = context.Request.QueryString; if (queryString["query"] != null) { Log.Info($"Receive request [{queryString["query"]}]."); var guidString = queryString["guid"]; if (guidString != null) { if (Guid.TryParse(guidString, out var clientGuid)) { var guidCancellationTokenSource = new CancellationTokenSource(); var guidCancellationToken = guidCancellationTokenSource.Token; TaskCancellationTokenSources[clientGuid] = guidCancellationTokenSource; try { await ComputationalAsyncCallback(serverArguments, context, guidCancellationToken); } catch (OperationCanceledException) { Log.Warn($"Task [{queryString["query"]}] cancelled while or after computing/sending response."); } catch (HttpListenerException) { Log.Warn("Response writing was aborted."); } } else { Log.Warn($"Bad request: guid [{guidString}] cannot be parsed."); } } else { Log.Warn("Bad request: no guid passed."); } } else if (queryString["cancel"] != null) { CancellationAsyncCallback(serverArguments, context); } else { Log.Warn("Bad request: neither query nor cancel."); } }); }
private static void CancellationAsyncCallback(ServerArguments serverArguments, HttpListenerContext context) { var cancellationGuidString = context.Request.QueryString["cancel"]; if (!Guid.TryParse(cancellationGuidString, out var cancelGuid)) { Log.Warn($"Cancellation guid [{cancellationGuidString}] cannot be parsed."); return; } if (!TaskCancellationTokenSources.ContainsKey(cancelGuid)) { Log.Warn($"Cancellation guid [{cancellationGuidString}] cannot be found."); return; } TaskCancellationTokenSources[cancelGuid].Cancel(false); TaskCancellationTokenSources[cancelGuid].Dispose(); TaskCancellationTokenSources.TryRemove(cancelGuid, out var _); }
public static bool TryGetArguments(string[] args, out ServerArguments parsedArguments) { var argumentsParser = new FluentCommandLineParser <ServerArguments>(); argumentsParser.Setup(a => a.Port).As('p', "port").Required(); argumentsParser.Setup(a => a.MethodName).As('n', "name").Required(); argumentsParser.Setup(a => a.MethodDuration).As('d', "duration") .WithDescription("Server will return his response in <duration> ms").Required(); argumentsParser.SetupHelp("?", "h", "help").Callback(text => Console.WriteLine(text)); var parsingResult = argumentsParser.Parse(args); if (parsingResult.HasErrors) { argumentsParser.HelpOption.ShowHelp(argumentsParser.Options); parsedArguments = null; return(false); } parsedArguments = argumentsParser.Object; return(!parsingResult.HasErrors); }
private static void Main(string[] args) { XmlConfigurator.Configure(); if (!ServerArguments.TryGetArguments(args, out var arguments)) { Console.WriteLine("Faulted: Pass arguments to preconfigurate server."); return; } var listener = new HttpListener() { Prefixes = { $"http://+:{arguments.Port}/{arguments.MethodName}/" } }; Log.Info($"Server is starting listening prefixes: {string.Join("; ", listener.Prefixes)}."); Log.Info("Press <ENTER> to stop listening."); listener.ProceedRequestsAsync(CreateAsyncCallback(arguments)); Console.ReadLine(); Log.Info("Server stopped."); }