proxy created
parent
d7f39d8a99
commit
da276b034f
|
|
@ -2,7 +2,7 @@
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"noxis-rs",
|
"noxis-rs",
|
||||||
"noxis-cli",
|
"noxis-cli", "noxis-proxy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[profile.dev]
|
[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