proxy created

migrate
prplV 2025-06-05 15:54:18 +03:00
parent d7f39d8a99
commit da276b034f
4 changed files with 113 additions and 1 deletions

View File

@ -2,7 +2,7 @@
resolver = "2" resolver = "2"
members = [ members = [
"noxis-rs", "noxis-rs",
"noxis-cli", "noxis-cli", "noxis-proxy",
] ]
[profile.dev] [profile.dev]

2
noxis-proxy/.env.example Normal file
View File

@ -0,0 +1,2 @@
NOXIS_SOCKET_PATH = "/path/to/noxis.sock"
NOXIS_PROXY_PORT = "numport"

12
noxis-proxy/Cargo.toml Normal file
View File

@ -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"

98
noxis-proxy/src/main.rs Normal file
View File

@ -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; // Дожидаемся завершения задачи
}