private async Task TerminateProcessAsync(string name, string token) { ProcessUpdateData data; if (token != this.Token) { this.Logger.Warning($"Attempt to terminate a remote process ({name}) with an invalid token."); data = new ProcessUpdateData(false, name); await this.BroadcastMessageAsync(MessageConstants.TERMINATE_IDENTIFIER, data.Serialize()); } else if (!this.States.ContainsKey(name)) { this.Logger.Warning($"Attempt to terminate a non-existing remote process ({name}). Discarding."); data = new ProcessUpdateData(false, name); await this.BroadcastMessageAsync(MessageConstants.TERMINATE_IDENTIFIER, data.Serialize()); } else { data = new ProcessUpdateData(true, name); await this.BroadcastMessageAsync(MessageConstants.TERMINATE_IDENTIFIER, data.Serialize()); this.States.Remove(name, out BaseClientState state); state.Dispose(); this.Logger.Nice("Process", ConsoleColor.Magenta, $"Terminating remote process | {name}"); } }
private async Task CompleteProcessUpdateTCSAsync(ProcessUpdateData updateData, TaskCompletionSource <bool> tcs) { if (updateData.Accepted && updateData.Name.Equals(this.Config.ProcessName)) { if (tcs != null) { tcs?.SetResult(updateData.Accepted); } else { await this.DisconnectAsync(); } } }
private async Task HandleUpdateProcessMessageAsync(Message msg, bool isRegisterUpdate) { if (msg.HasException) { return; //timeout } ProcessUpdateData updateData = msg.GetData <ProcessUpdateData>(); await this.CompleteProcessUpdateTCSAsync(updateData, isRegisterUpdate?this.RegisterTCS : this.UnregisterTCS); if (updateData.Accepted && !updateData.Name.Equals(this.Config.ProcessName)) { this.ProcessUpdate?.Invoke(updateData, isRegisterUpdate); } }
private async Task SendAsync(BaseClientState state, Message msg) { try { await state.SendAsync(msg); } catch (Exception ex) { this.Logger.Danger(ex); this.TerminateProcess(state.Name); ProcessUpdateData endData = new ProcessUpdateData(true, state.Name); await this.BroadcastMessageAsync(MessageConstants.TERMINATE_IDENTIFIER, endData.Serialize()); } }
private async Task ListenAsync(TCPSocketClientState state) { try { do { Stream stream = state.Stream; int bytesRead = await stream.ReadAsync(state.Buffer); if (bytesRead <= 0) { TcpState tcpState = state.GetTcpState(); if (tcpState != TcpState.Established) { this.Dispatcher.TerminateProcess(state.Name); ProcessUpdateData updateData = new ProcessUpdateData(true, state.Name); await this.Dispatcher.BroadcastMessageAsync(MessageConstants.TERMINATE_IDENTIFIER, updateData.Serialize()); return; } state.ClearBuffer(); await Task.Delay(10); continue; } string data = Encoding.UTF8.GetString(state.Buffer, 0, bytesRead); state.ClearBuffer(); List <Message> msgs = state.Reader.Read(data); await this.Dispatcher.HandleMessagesAsync(state, msgs); // Maximum register payload size is 395 bytes, the client is sending garbage. if (!state.IsRegistered && state.Reader.Size >= 600) { state.Reader.Clear(); } }while (!state.IsDisposed && state.IsRegistered); } catch (Exception e) { await this.ExceptionHandler.OnClientStateExceptionAsync(state, e); } }
private async Task RegisterProcessAsync(BaseClientState state, string name, string token) { ProcessUpdateData data; if (string.IsNullOrWhiteSpace(token) || token != this.Token) { this.Logger.Warning($"Attempt to register a remote process ({name}) with an invalid token ({token})."); data = new ProcessUpdateData(false, name); } else if (this.States.Count >= Config.Instance.MaxProcesses) { this.Logger.Warning($"Could not register a remote process ({name}), exceeding the maximum amount of remote processes"); data = new ProcessUpdateData(false, name); } else { bool shouldLog = true; if (this.States.ContainsKey(name)) { shouldLog = false; this.Logger.Nice("Process", ConsoleColor.Yellow, $"Overriding a remote process ({name})"); this.TerminateProcess(name, false); } state.Name = name; if (this.States.TryAdd(name, state)) { state.Register(); if (shouldLog) { this.Logger.Nice("Process", ConsoleColor.Magenta, $"Registering new remote process | {name}"); } data = new ProcessUpdateData(true, name); } else { this.Logger.Warning($"Could not register a remote process ({name}), this is due to concurrency issues"); data = new ProcessUpdateData(false, name); } } await this.BroadcastMessageAsync(MessageConstants.REGISTER_IDENTIFIER, data.Serialize()); }
private void OnProcessUpdate(ProcessUpdateData updateData, bool isRegisterUpdate) { bool procExists = this.Processes.ContainsKey(updateData.Name); if (isRegisterUpdate) { if (!procExists) { RemoteProcess proc = new RemoteProcess(this, updateData.Name); this.Processes.Add(updateData.Name, proc); this.ProcessRegistered?.Invoke(proc); } } else { if (procExists) { RemoteProcess proc = this.Processes[updateData.Name]; this.Processes.Remove(updateData.Name); this.ProcessEnded?.Invoke(proc); } } }