protected override async Task <long> ReadStreamInternal(Stream stream, long?length) { await Task.CompletedTask.ConfigureAwait(false); if (ReadOnly) { throw new NotSupportedException(); } Stream.Position = 0; using (var skip = new SkipableStream(Stream, 0)) { long readed; try { readed = skip.ReadFromStream(stream, length); } catch (IOException) { WebServerLog.Add(ServerLogType.Information, GetType(), "Send", "Connection closed by remote Host"); readed = Stream.Position; } Stream.SetLength(readed); return(readed); } }
public virtual void Start() { WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "Start Server on Port {0}", Settings.Port); ServerExecution = true; Listener = new TcpListener(new IPEndPoint(Settings.IPFilter, Settings.Port)); Listener.Start(); ServerThread = new Thread(ServerMainTask) { Name = "ServerThread - Port: " + Settings.Port.ToString() }; ServerThread.Start(); }
protected override async Task <long> WriteStreamInternal(Stream stream, long start, long?stop) { await Task.CompletedTask; Stream.Position = start; using (var skip = new SkipableStream(Stream, 0)) { try { return(skip.WriteToStream(stream, stop == null ? null : (long?)(stop.Value - start))); } catch (IOException) { WebServerLog.Add(ServerLogType.Information, GetType(), "Send", "Connection closed by remote Host"); return(Stream.Position - start); } } }
protected virtual async Task SafeClientStartListen(HttpConnection connection) { if (Debugger.IsAttached) { await ClientStartListen(connection).ConfigureAwait(false); } else { try { await ClientStartListen(connection).ConfigureAwait(false); } catch (Exception e) { WebServerLog.Add( ServerLogType.FatalError, GetType(), "Unhandled Exception", $"{e.GetType().FullName}: {e.Message} in {e.StackTrace}"); } } }
public async Task RunAsync( bool cancelFromConsoleEvent = true, #if NET5_0_OR_GREATER bool cancelFromAssemblyUnload = true, #endif bool cancelFromConsoleInput = false ) { var token = new CancellationTokenSource(); RunToken = token; if (cancelFromConsoleEvent) { Console.CancelKeyPress += (_, e) => { if (token != RunToken) { return; } e.Cancel = true; WebServerLog.Add( ServerLogType.Information, GetType(), "cancel", "console cancel received: {0}", e.SpecialKey ); if (!token.IsCancellationRequested) { token.Cancel(); } } } ; #if NET5_0_OR_GREATER if (cancelFromAssemblyUnload) { System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += _ => { if (token != RunToken) { return; } WebServerLog.Add( ServerLogType.Information, GetType(), "cancel", "assembly unload received" ); if (!token.IsCancellationRequested) { token.Cancel(); } } } ; #endif if (cancelFromConsoleInput) { _ = Task.Run(() => { if (token != RunToken) { return; } while (Console.Read() != (int)'q') { ; } WebServerLog.Add( ServerLogType.Information, GetType(), "cancel", "console key q received" ); if (!token.IsCancellationRequested) { token.Cancel(); } }); } if (!ServerExecution) { Start(); } try { await Task.Delay(-1, token.Token); } catch (TaskCanceledException) {} Stop(); }
protected virtual async Task ClientStartListen(HttpConnection connection) { connection.LastWorkTime = -1; if (connection.NetworkClient != null && connection.NetworkClient.Connected) { WebServerLog.Add(ServerLogType.Information, GetType(), "Connection", "Listen to Connection {0}", connection.NetworkClient?.Client.RemoteEndPoint); var task = PrepairProgressTask(connection); if (task == null) { WebServerLog.Add(ServerLogType.Information, GetType(), "Connection", $"Cannot establish data stream to {connection.Ip}"); RemoveConnection(connection); return; } var start = task.Monitor.Enabled ? DateTime.UtcNow : DateTime.MinValue; try { await ExecuteTaskChain(task).ConfigureAwait(false); } catch (Exception e) { task.Monitor.Current.Log("Unhandled exception: {0}", e); WebServerLog.Add(ServerLogType.Error, GetType(), "runtime exception", $"unhandled exception: {e}"); throw; } finally { if (Settings.MonitoringOutputDirectory is string monitorOut && task.Monitor.Enabled) { await task.Monitor.Save(monitorOut, start, task); } } if (task.SwitchProtocolHandler != null) { KeepAliveConnections.Remove(connection); AllConnections.Remove(connection); task.Dispose(); _ = task.SwitchProtocolHandler(); return; } if (task.Request.FieldConnection == HttpConnectionType.KeepAlive) { if (!KeepAliveConnections.Contains(connection)) { KeepAliveConnections.Add(connection); } } else { RemoveConnection(connection); } connection.LastWorkTime = Environment.TickCount; task.Dispose(); } else { RemoveConnection(connection); } }
protected virtual void ServerMainTask() { if (Listener == null) { return; } WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "Server successfully started"); var watch = new Stopwatch(); while (ServerExecution) { watch.Restart(); //request pending connections int step = 0; while (step < 10) { if (!Listener.Pending()) { break; } step++; ClientConnected(Listener.AcceptTcpClient()); } //request keep alive connections for (int i = 0; i < KeepAliveConnections.Count; ++i) { HttpConnection kas; try { kas = KeepAliveConnections[i]; } catch { continue; } if (kas == null) { continue; } if ((kas.NetworkClient != null && !kas.NetworkClient.Connected) || (kas.LastWorkTime != -1 && kas.LastWorkTime + Settings.ConnectionTimeout < Environment.TickCount ) ) { kas.NetworkClient?.Close(); kas.NetworkStream?.Dispose(); AllConnections.Remove(kas); KeepAliveConnections.Remove(kas); --i; continue; } if (kas.NetworkClient != null && kas.NetworkClient.Available > 0 && kas.LastWorkTime != -1 ) { _ = Task.Run(() => SafeClientStartListen(kas)); } } //Warten if (Listener.Pending()) { continue; } var delay = Settings.ConnectionDelay; if (delay > TimeSpan.Zero) { var time = delay - watch.Elapsed; if (time <= TimeSpan.Zero) { time = delay; } Thread.Sleep(time); } } watch.Stop(); Listener.Stop(); for (int i = 0; i < AllConnections.Count; ++i) { AllConnections[i].NetworkClient?.Close(); } AllConnections.Clear(); KeepAliveConnections.Clear(); WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "Server successfully stopped"); }
public virtual void Stop() { WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "Stopped Server"); ServerExecution = false; ServerThread?.Join(); }