proxy created
parent
d7f39d8a99
commit
da276b034f
|
|
@ -2,7 +2,7 @@
|
|||
resolver = "2"
|
||||
members = [
|
||||
"noxis-rs",
|
||||
"noxis-cli",
|
||||
"noxis-cli", "noxis-proxy",
|
||||
]
|
||||
|
||||
[profile.dev]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
NOXIS_SOCKET_PATH = "/path/to/noxis.sock"
|
||||
NOXIS_PROXY_PORT = "numport"
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "noxis-proxy"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.98"
|
||||
axum = { version = "0.8.4", features = ["ws"] }
|
||||
dotenv = "0.15.0"
|
||||
tokio = { version = "1.45.1", features = ["full"] }
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = "0.3.19"
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
use axum::{
|
||||
extract::{
|
||||
ws::{Message, WebSocket, WebSocketUpgrade},
|
||||
State,
|
||||
},
|
||||
response::IntoResponse,
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use std::{
|
||||
path::PathBuf, str::FromStr,
|
||||
};
|
||||
use tokio::net::UnixStream;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AppState {
|
||||
socket_path: PathBuf,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
dotenv::dotenv().ok();
|
||||
|
||||
tracing_subscriber::fmt()
|
||||
.with_max_level(tracing::Level::from_str(&std::env::var("NOXIS_LOG_LEVEL").unwrap_or_else(|_| String::from("INFO"))).unwrap_or_else(|_| tracing::Level::INFO))
|
||||
.with_writer(std::io::stdout)
|
||||
.compact()
|
||||
.init();
|
||||
|
||||
let app_state = AppState {
|
||||
socket_path : PathBuf::new().join(std::env::var("NOXIS_SOCKET_PATH").unwrap_or_else(|_| String::from("./noxis.sock")))
|
||||
};
|
||||
let app = Router::new()
|
||||
.route("/ws", get(ws_handler))
|
||||
.route("/hello", get(hello))
|
||||
.with_state(app_state);
|
||||
|
||||
let bind = format!("0.0.0.0:{}", std::env::var("NOXIS_PROXY_PORT").unwrap_or_else(|_| String::from("3000")));
|
||||
|
||||
tracing::info!("Serving on {}", &bind);
|
||||
|
||||
let listener = tokio::net::TcpListener::bind(bind)
|
||||
.await?;
|
||||
axum::serve(listener, app).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn ws_handler(
|
||||
ws: WebSocketUpgrade,
|
||||
State(state): State<AppState>,
|
||||
) -> impl IntoResponse {
|
||||
tracing::info!("New WebSocket connection");
|
||||
ws.on_upgrade(|socket| handle_socket(socket, state))
|
||||
}
|
||||
|
||||
async fn hello(
|
||||
State(_state): State<AppState>,
|
||||
) -> impl IntoResponse {
|
||||
String::from("HELLO")
|
||||
}
|
||||
|
||||
async fn handle_socket(mut ws: WebSocket, state: AppState) {
|
||||
// Подключаемся к Unix-сокету
|
||||
tracing::info!("handle websocket");
|
||||
let mut unix_socket = match UnixStream::connect(&state.socket_path).await {
|
||||
Ok(socket) => socket,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to connect to Unix socket: {}", e);
|
||||
let _ = ws.send(Message::Text("ERROR: Unix socket connection failed".into())).await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Отправляем сообщения из WS → Unix
|
||||
let ws_receiver = tokio::spawn(async move {
|
||||
while let Some(Ok(msg)) = ws.recv().await {
|
||||
if let Message::Text(text) = msg {
|
||||
if let Err(e) = unix_socket.write_all(text.as_bytes()).await {
|
||||
eprintln!("Failed to write to Unix socket: {}", e);
|
||||
break;
|
||||
}
|
||||
let mut buf = Vec::new();
|
||||
match unix_socket.read_to_end(&mut buf).await {
|
||||
Ok(n) if n > 0 => {
|
||||
let response = String::from_utf8_lossy(&buf[..n]);
|
||||
if ws.send(Message::Text(response.into_owned().into())).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(_) | Err(_) => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let _ = ws_receiver.await; // Дожидаемся завершения задачи
|
||||
}
|
||||
Loading…
Reference in New Issue