Created
March 21, 2022 02:52
-
-
Save snuffyDev/780da1b6038ad5ab1d7e89e192913d2c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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