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-verbosity-flag = "2.1.2"
|
||||
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]
|
||||
default = ["server", "client"]
|
||||
client = []
|
||||
server = []
|
||||
default = ["server"]
|
||||
server = ["dep:threadpool"]
|
||||
|
|
|
@ -41,10 +41,17 @@ pub(crate) struct Cli {
|
|||
#[arg(long)]
|
||||
pub(crate) meta: bool,
|
||||
|
||||
// host a server instead of connecting to one
|
||||
#[cfg(feature = "server")]
|
||||
#[arg(short, long, default_value_t = false)]
|
||||
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)]
|
||||
pub(crate) mode: Mode,
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt::Display;
|
||||
use clap::ValueEnum;
|
||||
use crate::common::args::Cli;
|
||||
use clap::ValueEnum;
|
||||
use std::fmt::Display;
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Mode {
|
||||
Tcp,
|
||||
|
@ -37,13 +37,18 @@ impl Display for Mode {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Config {
|
||||
cli: Cli,
|
||||
addr: std::net::SocketAddr,
|
||||
pub struct Config {
|
||||
pub addr: std::net::SocketAddr,
|
||||
pub mode: Mode,
|
||||
pub threads: usize
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(cli: Cli, addr: std::net::SocketAddr) -> Self {
|
||||
Config { cli, addr }
|
||||
pub fn new(cli: &Cli) -> Self {
|
||||
Config {
|
||||
addr: cli.addr.clone(),
|
||||
mode: cli.mode.clone(),
|
||||
threads: cli.threads
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,2 @@
|
|||
|
||||
pub mod args;
|
||||
use args::*;
|
||||
|
||||
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
|
||||
//! every connection. But I had to make it for some reason.
|
||||
|
||||
use anyhow::Result;
|
||||
use libpt::log::*;
|
||||
|
||||
mod client;
|
||||
|
@ -11,15 +12,21 @@ mod server;
|
|||
|
||||
use common::{args::Cli, conf::*};
|
||||
|
||||
fn main() {
|
||||
use crate::server::Server;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let cli = Cli::cli_parse();
|
||||
debug!("dumping cli args:\n{:#?}", cli);
|
||||
|
||||
let cfg = Config::new(&cli);
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
if cli.server {
|
||||
info!("starting server");
|
||||
|
||||
return;
|
||||
Server::build(cfg)?.run()?;
|
||||
return Ok(());
|
||||
}
|
||||
// implicit else, so we can work without the server feature
|
||||
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