/// <summary> /// Sends the given output, in a blocking fashion. /// </summary> public bool SendOutput(TorXakisAction action) { lock (locker) { if (streamWriter != null) { try { // TorXakis expects \n terminated lines (Linux), not \r\n terminated lines (Windows)! streamWriter.Write(action.Data + "\n"); streamWriter.Flush(); return(true); } catch (Exception e) { Log.Error(this, nameof(SendOutput) + " exception: " + this, e); return(false); } } else { return(false); } } }
/// <summary>Fires the event: <see cref="InputReceived"/></summary> private void OnInputReceived(TorXakisAction action) { // Sanity checks. if (action.Type != ActionType.Input) { throw new ArgumentException("Not input: " + action); } Log.Info(this, nameof(InputReceived) + ": " + action); InputReceived?.Invoke(action); }
/// <summary> /// Sends the given output, in a blocking fashion. /// </summary> public bool SendOutput(TorXakisAction action) { lock (locker) { // Sanity checks. if (action.Type != ActionType.Output) { throw new ArgumentException("Not output: " + action); } TorXakisConnection connection = connections.Values.FirstOrDefault(x => x.OutputChannel == action.Channel); if (connection == null) { throw new Exception("Connection not found for: " + action); } Log.Info(this, nameof(SendOutput) + ": " + action); return(connection.SendOutput(action)); } }
/// <summary> /// The main thread loop: first accepting a connection, then listening for incoming messages. /// </summary> private void ThreadLoop() { try { GoToState(States.Started); tcpListener = new TcpListener(IPAddress.Any, Port); tcpListener.Start(); Log.Info(this, "Waiting for TCP connection: " + tcpListener.LocalEndpoint); tcpClient = tcpListener.AcceptTcpClient(); tcpClient.NoDelay = true; Log.Info(this, "Connected TCP client: " + tcpListener.LocalEndpoint); NetworkStream stream = tcpClient.GetStream(); // TorXakis expects UTF-8 encoding without BOM! streamReader = new StreamReader(stream, new UTF8Encoding(false)); streamWriter = new StreamWriter(stream, new UTF8Encoding(false)); GoToState(States.Connected); while (true) { string data = ReceiveInput(); TorXakisAction action = TorXakisAction.FromInput(InputChannel, data); OnInputReceived(action); } } catch (ThreadAbortException) { // This exception is normal when shutting down. } catch (Exception e) { Log.Error(this, nameof(ThreadLoop) + " exception: " + this, e); } finally { Dispose(); } }
/// <summary> /// Callback for <see cref="TorXakisConnection.InputReceived"/>. /// </summary> private void Connection_InputReceived(TorXakisAction action) { OnInputReceived(action); }
/// <summary>Fires the event:<see cref="InputReceived"/></summary> private void OnInputReceived(TorXakisAction action) { InputReceived?.Invoke(action); }