feat: add initial server + routes
This commit is contained in:
parent
908d6bd67b
commit
d61e6da1d2
@ -14,6 +14,7 @@ serde_json = "1.0.140"
|
|||||||
sqlx = { version = "0.8.5", features = ["macros", "runtime-tokio", "sqlite", "uuid"] }
|
sqlx = { version = "0.8.5", features = ["macros", "runtime-tokio", "sqlite", "uuid"] }
|
||||||
tokio = { version = "1.44.2", features = ["full"] }
|
tokio = { version = "1.44.2", features = ["full"] }
|
||||||
tower = "0.5.2"
|
tower = "0.5.2"
|
||||||
|
tower-http = { version = "0.6.4", features = ["fs"] }
|
||||||
tracing = { version = "0.1.41", features = ["async-await"] }
|
tracing = { version = "0.1.41", features = ["async-await"] }
|
||||||
tracing-subscriber = "0.3.19"
|
tracing-subscriber = "0.3.19"
|
||||||
uuid = { version = "1.16.0", features = ["v4"] }
|
uuid = { version = "1.16.0", features = ["v4"] }
|
||||||
|
19
src/lib.rs
19
src/lib.rs
@ -1,2 +1,21 @@
|
|||||||
|
#![allow(clippy::unwrap_used)]
|
||||||
|
use router::new_router;
|
||||||
|
use tokio::net::TcpListener;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
mod db;
|
mod db;
|
||||||
|
mod router;
|
||||||
mod script;
|
mod script;
|
||||||
|
|
||||||
|
pub fn run() {
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
rt.block_on(async {
|
||||||
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
|
let app = new_router();
|
||||||
|
|
||||||
|
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
|
info!("listening"=?listener.local_addr().unwrap());
|
||||||
|
axum::serve(listener, app).await.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
148
src/main.rs
148
src/main.rs
@ -1,16 +1,13 @@
|
|||||||
#![allow(clippy::unwrap_used, clippy::expect_used)]
|
#![allow(dead_code, clippy::unwrap_used, clippy::expect_used)]
|
||||||
use axum::{
|
use axum::{
|
||||||
Router,
|
// Router,
|
||||||
extract::ws::{Message, WebSocket, WebSocketUpgrade},
|
extract::ws::{Message, WebSocket, WebSocketUpgrade},
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
routing::get,
|
// routing::get,
|
||||||
};
|
};
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
use std::{
|
use std::sync::{Arc, Mutex};
|
||||||
sync::{Arc, Mutex},
|
use tokio::task;
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
use tokio::{task, time};
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
@ -20,87 +17,44 @@ use tokio::sync::mpsc; // Use std::process::Stdio
|
|||||||
|
|
||||||
type Tx = tokio::sync::mpsc::UnboundedSender<Message>;
|
type Tx = tokio::sync::mpsc::UnboundedSender<Message>;
|
||||||
|
|
||||||
#[tokio::main]
|
fn main() {
|
||||||
async fn main() {
|
befehlswerk::run();
|
||||||
tracing_subscriber::fmt().pretty().init();
|
|
||||||
let clients = Arc::new(Mutex::new(Vec::<Tx>::new()));
|
|
||||||
let clients_clone = Arc::clone(&clients);
|
|
||||||
|
|
||||||
let (tx, mut rx) = mpsc::channel(100);
|
|
||||||
|
|
||||||
task::spawn(async move {
|
|
||||||
let cmd = "$count = 0; while($count -lt 10000) {
|
|
||||||
#Write-Error 'test-error'
|
|
||||||
#write-warning 'test-warning'
|
|
||||||
Write-Output \"$(Get-Date -Format 'yyyy-MM-dd_HH:mm:ss'): Hello World #$($count) from PowerShell!\"
|
|
||||||
$count += 1
|
|
||||||
}";
|
|
||||||
spawn_and_capture(cmd, tx).await;
|
|
||||||
});
|
|
||||||
|
|
||||||
// In batches - but this does not preserve the order. Or does it? It's possible that stdout is
|
|
||||||
// faster than stderr.
|
|
||||||
task::spawn(async move {
|
|
||||||
loop {
|
|
||||||
let mut closed = vec![];
|
|
||||||
|
|
||||||
let mut messages = vec![];
|
|
||||||
|
|
||||||
if rx.recv_many(&mut messages, 2000).await > 0 {
|
|
||||||
let msg = Message::Text(
|
|
||||||
messages
|
|
||||||
.into_iter()
|
|
||||||
.map(|m| if m.1 { format!("[ERR]: {}", m.0) } else { m.0 })
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n")
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
{
|
|
||||||
let mut lock = clients_clone.lock().unwrap();
|
|
||||||
for (i, tx) in lock.iter().enumerate() {
|
|
||||||
if tx.send(msg.clone()).is_err() {
|
|
||||||
closed.push(i);
|
|
||||||
}
|
}
|
||||||
}
|
// #[tokio::main]
|
||||||
|
// async fn main() {
|
||||||
for i in closed.iter().rev() {
|
// tracing_subscriber::fmt().pretty().init();
|
||||||
lock.remove(*i);
|
// let clients = Arc::new(Mutex::new(Vec::<Tx>::new()));
|
||||||
}
|
// let clients_clone = Arc::clone(&clients);
|
||||||
}
|
|
||||||
//for message in messages {
|
|
||||||
// let msg = Message::Text(if message.1 {
|
|
||||||
// format!("[ERR]: {}", message.0).into()
|
|
||||||
// } else {
|
|
||||||
// message.0.into()
|
|
||||||
// });
|
|
||||||
// {
|
|
||||||
// let mut lock = clients_clone.lock().unwrap();
|
|
||||||
// for (i, tx) in lock.iter().enumerate() {
|
|
||||||
// if tx.send(msg.clone()).is_err() {
|
|
||||||
// closed.push(i);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
// for i in closed.iter().rev() {
|
// let (tx, mut rx) = mpsc::channel(100);
|
||||||
// lock.remove(*i);
|
//
|
||||||
// }
|
// task::spawn(async move {
|
||||||
// }
|
// let cmd = "$count = 0; while($count -lt 10000) {
|
||||||
//}
|
// #Write-Error 'test-error'
|
||||||
}
|
// #write-warning 'test-warning'
|
||||||
//time::sleep(Duration::from_millis(500)).await;
|
// Write-Output \"$(Get-Date -Format 'yyyy-MM-dd_HH:mm:ss'): Hello World #$($count) from PowerShell!\"
|
||||||
}
|
// $count += 1
|
||||||
});
|
// }";
|
||||||
|
// spawn_and_capture(cmd, tx).await;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // In batches - but this does not preserve the order. Or does it? It's possible that stdout is
|
||||||
|
// // faster than stderr.
|
||||||
// task::spawn(async move {
|
// task::spawn(async move {
|
||||||
// loop {
|
// loop {
|
||||||
// let mut closed = vec![];
|
// let mut closed = vec![];
|
||||||
//
|
//
|
||||||
// if let Some((line, is_err)) = rx.recv().await {
|
// let mut messages = vec![];
|
||||||
// let msg = Message::Text(if is_err {
|
//
|
||||||
// format!("[ERR]: {line}").into()
|
// if rx.recv_many(&mut messages, 2000).await > 0 {
|
||||||
// } else {
|
// let msg = Message::Text(
|
||||||
// line.into()
|
// messages
|
||||||
// });
|
// .into_iter()
|
||||||
|
// .map(|m| if m.1 { format!("[ERR]: {}", m.0) } else { m.0 })
|
||||||
|
// .collect::<Vec<_>>()
|
||||||
|
// .join("\n")
|
||||||
|
// .into(),
|
||||||
|
// );
|
||||||
// {
|
// {
|
||||||
// let mut lock = clients_clone.lock().unwrap();
|
// let mut lock = clients_clone.lock().unwrap();
|
||||||
// for (i, tx) in lock.iter().enumerate() {
|
// for (i, tx) in lock.iter().enumerate() {
|
||||||
@ -113,25 +67,21 @@ async fn main() {
|
|||||||
// lock.remove(*i);
|
// lock.remove(*i);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// //time::sleep(Duration::from_millis(200)).await;
|
|
||||||
// } else {
|
|
||||||
// break;
|
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
|
//
|
||||||
let app = Router::new().route(
|
// let app = Router::new().route(
|
||||||
"/ws",
|
// "/ws",
|
||||||
get({
|
// get({
|
||||||
let clients = Arc::clone(&clients);
|
// let clients = Arc::clone(&clients);
|
||||||
move |ws| handle_socket(ws, Arc::clone(&clients))
|
// move |ws| handle_socket(ws, Arc::clone(&clients))
|
||||||
}),
|
// }),
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
axum::serve(listener, app).await.unwrap();
|
// axum::serve(listener, app).await.unwrap();
|
||||||
}
|
// }
|
||||||
|
|
||||||
async fn handle_socket(ws: WebSocketUpgrade, clients: Arc<Mutex<Vec<Tx>>>) -> impl IntoResponse {
|
async fn handle_socket(ws: WebSocketUpgrade, clients: Arc<Mutex<Vec<Tx>>>) -> impl IntoResponse {
|
||||||
ws.on_upgrade(move |socket| handle_ws(socket, clients))
|
ws.on_upgrade(move |socket| handle_ws(socket, clients))
|
||||||
|
11
src/router.rs
Normal file
11
src/router.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use axum::routing::{get, get_service};
|
||||||
|
use routes::scripts::get_scripts;
|
||||||
|
use tower_http::services::ServeDir;
|
||||||
|
mod routes;
|
||||||
|
|
||||||
|
pub fn new_router() -> axum::Router {
|
||||||
|
axum::Router::new()
|
||||||
|
.fallback_service(get_service(ServeDir::new("assets")))
|
||||||
|
// .nest_service("/", ServeDir::new("assets"))
|
||||||
|
.route("/scripts", get(get_scripts))
|
||||||
|
}
|
1
src/router/routes.rs
Normal file
1
src/router/routes.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod scripts;
|
14
src/router/routes/scripts.rs
Normal file
14
src/router/routes/scripts.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use axum::response::{Html, IntoResponse};
|
||||||
|
|
||||||
|
pub async fn get_scripts() -> impl IntoResponse {
|
||||||
|
Html(
|
||||||
|
r##"
|
||||||
|
<section id="scripts">
|
||||||
|
<ul>
|
||||||
|
<li>Script1</li>
|
||||||
|
<li>Script2</li>
|
||||||
|
</ul>
|
||||||
|
<button hx-get="/scripts" hx-swap="outerHTML" hx-target="#scripts">Refresh</button>
|
||||||
|
</section>"##,
|
||||||
|
)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user