generated from PlexSheep/rs-base
a very primitive "server"
cargo devel CI / cargo CI (push) Successful in 2m14s
Details
cargo devel CI / cargo CI (push) Successful in 2m14s
Details
This commit is contained in:
parent
a212cfff83
commit
78340a23d2
|
@ -18,9 +18,9 @@ clap = "4.4.18"
|
||||||
clap-num = "1.0.2"
|
clap-num = "1.0.2"
|
||||||
clap-verbosity-flag = "2.1.2"
|
clap-verbosity-flag = "2.1.2"
|
||||||
libpt = { version = "0.3.10", features = ["net"] }
|
libpt = { version = "0.3.10", features = ["net"] }
|
||||||
threadpool = "1.8.1"
|
mio = { version = "0.8.10", features = ["net", "os-poll"] }
|
||||||
|
threadpool = { version = "1.8.1", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["server", "client"]
|
default = ["server"]
|
||||||
client = []
|
server = ["dep:threadpool"]
|
||||||
server = []
|
|
||||||
|
|
|
@ -41,10 +41,17 @@ pub(crate) struct Cli {
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub(crate) meta: bool,
|
pub(crate) meta: bool,
|
||||||
|
|
||||||
|
// host a server instead of connecting to one
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
#[arg(short, long, default_value_t = false)]
|
#[arg(short, long, default_value_t = false)]
|
||||||
pub(crate) server: bool,
|
pub(crate) server: bool,
|
||||||
|
|
||||||
|
|
||||||
|
// how much threads the server should use
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
#[arg(short, long, default_value_t = 4)]
|
||||||
|
pub(crate) threads: usize,
|
||||||
|
|
||||||
#[arg(short, long, default_value_t = Mode::Tcp, ignore_case = true)]
|
#[arg(short, long, default_value_t = Mode::Tcp, ignore_case = true)]
|
||||||
pub(crate) mode: Mode,
|
pub(crate) mode: Mode,
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::fmt::Display;
|
|
||||||
use clap::ValueEnum;
|
|
||||||
use crate::common::args::Cli;
|
use crate::common::args::Cli;
|
||||||
|
use clap::ValueEnum;
|
||||||
|
use std::fmt::Display;
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
Tcp,
|
Tcp,
|
||||||
|
@ -37,13 +37,18 @@ impl Display for Mode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct Config {
|
pub struct Config {
|
||||||
cli: Cli,
|
pub addr: std::net::SocketAddr,
|
||||||
addr: std::net::SocketAddr,
|
pub mode: Mode,
|
||||||
|
pub threads: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new(cli: Cli, addr: std::net::SocketAddr) -> Self {
|
pub fn new(cli: &Cli) -> Self {
|
||||||
Config { cli, addr }
|
Config {
|
||||||
|
addr: cli.addr.clone(),
|
||||||
|
mode: cli.mode.clone(),
|
||||||
|
threads: cli.threads
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,2 @@
|
||||||
|
|
||||||
pub mod args;
|
pub mod args;
|
||||||
use args::*;
|
|
||||||
|
|
||||||
pub mod conf;
|
pub mod conf;
|
||||||
use conf::*;
|
|
||||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -3,6 +3,7 @@
|
||||||
//! over a connection, while letting a server reply pong to
|
//! over a connection, while letting a server reply pong to
|
||||||
//! every connection. But I had to make it for some reason.
|
//! every connection. But I had to make it for some reason.
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
use libpt::log::*;
|
use libpt::log::*;
|
||||||
|
|
||||||
mod client;
|
mod client;
|
||||||
|
@ -11,15 +12,21 @@ mod server;
|
||||||
|
|
||||||
use common::{args::Cli, conf::*};
|
use common::{args::Cli, conf::*};
|
||||||
|
|
||||||
fn main() {
|
use crate::server::Server;
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
let cli = Cli::cli_parse();
|
let cli = Cli::cli_parse();
|
||||||
debug!("dumping cli args:\n{:#?}", cli);
|
debug!("dumping cli args:\n{:#?}", cli);
|
||||||
|
|
||||||
|
let cfg = Config::new(&cli);
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
if cli.server {
|
if cli.server {
|
||||||
info!("starting server");
|
info!("starting server");
|
||||||
|
Server::build(cfg)?.run()?;
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
// implicit else, so we can work without the server feature
|
// implicit else, so we can work without the server feature
|
||||||
info!("starting client");
|
info!("starting client");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
use std::net::TcpListener;
|
||||||
|
|
||||||
|
pub trait Listener {}
|
||||||
|
pub trait Stream {}
|
||||||
|
|
||||||
|
impl Listener for TcpListener {}
|
|
@ -0,0 +1,66 @@
|
||||||
|
#![cfg(feature = "server")]
|
||||||
|
use anyhow::Result;
|
||||||
|
use libpt::log::{error, info};
|
||||||
|
use mio::{self, event::Event, net::TcpListener, Events, Interest, Poll, Token};
|
||||||
|
use std::{
|
||||||
|
io::{prelude::*, BufReader},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
use threadpool::ThreadPool;
|
||||||
|
|
||||||
|
use crate::common::conf::{Config, Mode};
|
||||||
|
|
||||||
|
pub mod listener;
|
||||||
|
use listener::*;
|
||||||
|
|
||||||
|
const EVENT_CAPACITY: usize = 128;
|
||||||
|
const SERVER: Token = Token(0);
|
||||||
|
|
||||||
|
pub struct Server {
|
||||||
|
cfg: Config,
|
||||||
|
work: Poll,
|
||||||
|
events: Events,
|
||||||
|
pool: ThreadPool,
|
||||||
|
pub timeout: Option<Duration>,
|
||||||
|
server: TcpListener,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Server {
|
||||||
|
pub fn build(cfg: Config) -> Result<Self> {
|
||||||
|
let mut server = TcpListener::bind(cfg.addr)?;
|
||||||
|
let poll: Poll = Poll::new()?;
|
||||||
|
poll.registry()
|
||||||
|
.register(&mut server, SERVER, Interest::READABLE | Interest::WRITABLE);
|
||||||
|
let events: Events = Events::with_capacity(EVENT_CAPACITY);
|
||||||
|
let pool = ThreadPool::new(cfg.threads);
|
||||||
|
let timeout = Some(Duration::from_secs(5));
|
||||||
|
Ok(Server {
|
||||||
|
cfg,
|
||||||
|
work: poll,
|
||||||
|
events,
|
||||||
|
pool,
|
||||||
|
timeout,
|
||||||
|
server,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn run(&mut self) -> Result<()> {
|
||||||
|
loop {
|
||||||
|
self.work.poll(&mut self.events, self.timeout)?;
|
||||||
|
for event in self.events.iter() {
|
||||||
|
// self.pool.execute(|| {
|
||||||
|
let result = self.handle_event(event);
|
||||||
|
if let Err(err) = result {
|
||||||
|
error!("Error while handling server event {:?}: {:?}", event, err);
|
||||||
|
}
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_event(&self, event: &Event) -> Result<()> {
|
||||||
|
dbg!(event);
|
||||||
|
let connection = self.server.accept()?;
|
||||||
|
info!("received a connection!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue