use std::sync::Arc;
use anyhow::Result;
use log::{error, info};
pub use clap::Parser;
use crate::protocol::ServerProtocol;
use crate::wslink::WsLinkAsync;
#[derive(Parser, Debug, Clone)]
pub struct ServerArgument {
#[clap(long, default_value = "localhost")]
pub host: String,
#[clap(short, long, default_value = "3001")]
pub port: usize,
#[clap(short, long, default_value = "wslink-secret")]
pub auth_key: String,
}
pub async fn start<Protocol: ServerProtocol + Default + 'static>() {
let args = ServerArgument::parse();
let protocol = Protocol::default();
let (ws_handler, mut ws_local) = WsLinkAsync::new(protocol, &args);
tokio::task::spawn_blocking(move || ws_local.run());
match tokio::spawn(inner_start(ws_handler.clone(), args.clone())).await {
Ok(Ok(())) => {}
Ok(Err(err)) => error!("wslink server failed: {:#}", err),
Err(err) => error!("wslink server task join failed: {}", err),
}
ws_handler.shutdown().await;
}
async fn inner_start(ws_handler: Arc<WsLinkAsync>, args: ServerArgument) -> Result<()> {
let listener = tokio::net::TcpListener::bind(format!("{}:{}", args.host, args.port)).await?;
info!("Listening on: {}:{}", args.host, args.port);
info!("wslink started");
loop {
match listener.accept().await {
Ok((stream, _)) => {
let future = ws_handler.clone().handle_connect(stream);
tokio::spawn(future);
}
Err(err) => {
error!("failed to accept websocket connection: {}", err);
return Err(err.into());
}
}
}
}