Skip to content

Instantly share code, notes, and snippets.

@snuffyDev
Created March 21, 2022 02:52
Show Gist options
  • Save snuffyDev/780da1b6038ad5ab1d7e89e192913d2c to your computer and use it in GitHub Desktop.
Save snuffyDev/780da1b6038ad5ab1d7e89e192913d2c to your computer and use it in GitHub Desktop.
pub mod terminal;
use futures_util::{SinkExt, StreamExt};
use std::{io::Write, net::SocketAddr};
use terminal::{Pty, PtyProcess};
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader};
use tokio::net::{TcpListener, TcpStream};
use tokio::process::{ChildStderr, ChildStdin, ChildStdout};
use tokio_tungstenite::tungstenite::Result;
use tokio_tungstenite::{accept_async, tungstenite::Error, tungstenite::Message};
async fn accept_connection(peer: SocketAddr, stream: TcpStream, process: PtyProcess) {
if let Err(e) = handle_connection(peer, stream, process).await {
match e {
Error::ConnectionClosed | Error::Protocol(_) | Error::Utf8 => (),
err => println!("Error processing connection: {}", err),
}
}
}
async fn handle_connection(peer: SocketAddr, stream: TcpStream, process: PtyProcess) -> Result<()> {
let mut ws_stream = accept_async(stream).await.expect("Failed to accept");
println!("New WebSocket connection: {}", peer);
let mut term = process.lock().await;
// let stdout = term.stdout.\taoe);
let stdout = term.stdout.take();
let mut reader = BufReader::new(stdout.unwrap()).lines();
while let Some(msg) = ws_stream.next().await {
let msg = msg?;
let mut buffer_output = String::new();
println!("message: {}", &msg);
// #### HERE
if msg.is_text() || msg.is_binary() {
let term_cmd = msg.clone();
let mut stdin = term.stdin.take().expect("error taking");
let send_cmd = tokio::task::spawn(async move {
let input_cmd = &term_cmd.clone().into_text().expect("Serialize failure");
let input_cmd = String::from(input_cmd);
stdin.write(input_cmd.as_bytes()).await.expect("");
stdin.flush().await.expect("failed to flush");
drop(std_in);
// std_in.flush().await.expect("Failed to flush stdin")
});
// let stdout = term.stdout.take().expect("Failed to open stdout");
while let Some(line) = reader.next_line().await? {
println!("Line: {}", line);
let temp_string = format!("{}\n", line);
buffer_output.push_str(temp_string.as_str());
}
ws_stream
.send(Message::Text(buffer_output))
.await
.expect("uh oh");
}
}
Ok(())
}
#[tokio::main]
async fn main() {
// env_logger::init();
let addr = "127.0.0.1:9002";
let listener = TcpListener::bind(&addr)
.await
.expect("Can't listen to provided address");
let pty = Pty::new().await;
println!("Listening on: {}", addr);
while let Ok((stream, _)) = listener.accept().await {
let process = pty.process.clone();
let peer = stream
.peer_addr()
.expect("connected streams should have a peer address");
println!("Peer address: {}", peer);
tokio::spawn(accept_connection(peer, stream, process));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment