refactor: ♻️ file organizations
This commit is contained in:
parent
527886676c
commit
88c1b2517c
7 changed files with 195 additions and 68 deletions
2
configs/client_config.toml
Normal file
2
configs/client_config.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[client_config]
|
||||||
|
server_address = "127.0.0.1:2554"
|
2
configs/server_config.toml
Normal file
2
configs/server_config.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[server_config]
|
||||||
|
server_address = "127.0.0.1:2554"
|
45
src/client.rs
Normal file
45
src/client.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
use std::{net::SocketAddr, path::Path};
|
||||||
|
|
||||||
|
use s2n_quic::{Client, client::Connect};
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
|
use crate::ClientConfig;
|
||||||
|
|
||||||
|
pub async fn run<'a>(client_config: ClientConfig<'a>) {
|
||||||
|
let client = Client::builder()
|
||||||
|
.with_io("0:0")
|
||||||
|
.unwrap()
|
||||||
|
.with_tls(Path::new("certificates/cert.pem"))
|
||||||
|
.unwrap()
|
||||||
|
.start()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("Client Address = {}", client.local_addr().unwrap());
|
||||||
|
let connect = Connect::new(client_config.server_address.parse::<SocketAddr>().unwrap())
|
||||||
|
.with_server_name("localhost");
|
||||||
|
let mut connection = match client.connect(connect).await {
|
||||||
|
Ok(connection) => connection,
|
||||||
|
Err(err_val) => {
|
||||||
|
eprintln!("Error: Client Connection | {}", err_val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connection.keep_alive(true).unwrap();
|
||||||
|
|
||||||
|
let stream = connection.open_bidirectional_stream().await.unwrap();
|
||||||
|
let (mut receive_stream, mut send_stream) = stream.split();
|
||||||
|
send_stream
|
||||||
|
.send("Hi from Tahinli".as_bytes().into())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let received = receive_stream.receive().await.unwrap().unwrap();
|
||||||
|
println!("{}", String::from_utf8(received.to_vec()).unwrap());
|
||||||
|
|
||||||
|
if let Err(err_val) = send_stream.close().await {
|
||||||
|
eprintln!("Error: Stream Close | {}", err_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err_val) = send_stream.shutdown().await {
|
||||||
|
eprintln!("Error: Stream Shutdown| {}", err_val);
|
||||||
|
}
|
||||||
|
}
|
91
src/lib.rs
Normal file
91
src/lib.rs
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
use std::{collections::VecDeque, env, fs::File, io::Read};
|
||||||
|
|
||||||
|
mod client;
|
||||||
|
mod server;
|
||||||
|
mod voice;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct TOML {
|
||||||
|
header: String,
|
||||||
|
fields: VecDeque<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
const SERVER_CONFIG_FILE_LOCATION: &str = "configs/server_config.toml";
|
||||||
|
const CLIENT_CONFIG_FILE_LOCATION: &str = "configs/client_config.toml";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ServerConfig<'a> {
|
||||||
|
server_address: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ClientConfig<'a> {
|
||||||
|
server_address: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn server() {
|
||||||
|
let mut config = naive_toml_parser(SERVER_CONFIG_FILE_LOCATION);
|
||||||
|
|
||||||
|
if config.header.as_str() == "server_config" {
|
||||||
|
let server_config = ServerConfig {
|
||||||
|
server_address: &config.fields.pop_front().unwrap(),
|
||||||
|
};
|
||||||
|
server::run(server_config).await;
|
||||||
|
} else {
|
||||||
|
eprintln!("Error: Server Config File Couldn't Be Parsed Correctly");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn client() {
|
||||||
|
let mut config = naive_toml_parser(CLIENT_CONFIG_FILE_LOCATION);
|
||||||
|
|
||||||
|
if config.header.as_str() == "client_config" {
|
||||||
|
let client_config = ClientConfig {
|
||||||
|
server_address: &config.fields.pop_front().unwrap(),
|
||||||
|
};
|
||||||
|
client::run(client_config).await;
|
||||||
|
} else {
|
||||||
|
eprintln!("Error: Client Config File Couldn't Be Parsed Correctly");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start() {
|
||||||
|
match env::args().collect::<Vec<String>>().get(1) {
|
||||||
|
Some(arg) => match arg.as_str() {
|
||||||
|
"-c" | "--client" => client().await,
|
||||||
|
"-s" | "--server" => server().await,
|
||||||
|
_ => return,
|
||||||
|
},
|
||||||
|
None => return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn naive_toml_parser(file_location: &str) -> TOML {
|
||||||
|
let mut toml_file = File::open(file_location).unwrap();
|
||||||
|
let mut toml_ingredients = String::default();
|
||||||
|
toml_file.read_to_string(&mut toml_ingredients).unwrap();
|
||||||
|
let mut toml_ingredients = toml_ingredients.lines().collect::<VecDeque<&str>>();
|
||||||
|
|
||||||
|
let header = toml_ingredients
|
||||||
|
.pop_front()
|
||||||
|
.unwrap()
|
||||||
|
.replace('[', "")
|
||||||
|
.replace(']', "")
|
||||||
|
.trim_end()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let fields = toml_ingredients
|
||||||
|
.iter()
|
||||||
|
.map(|ingredient| {
|
||||||
|
ingredient
|
||||||
|
.split_once('=')
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.replace('"', "")
|
||||||
|
.trim()
|
||||||
|
.to_string()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
TOML { header, fields }
|
||||||
|
}
|
70
src/main.rs
70
src/main.rs
|
@ -1,74 +1,8 @@
|
||||||
use std::{net::SocketAddr, path::Path, time::Duration};
|
use voice_chat::start;
|
||||||
|
|
||||||
use s2n_quic::{Client, Server, client::Connect};
|
|
||||||
|
|
||||||
const SERVER_ADDRESS: &str = "127.0.0.1:2021";
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
|
||||||
tokio::spawn(server());
|
start().await;
|
||||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
||||||
client().await;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn server() {
|
|
||||||
let mut server = Server::builder()
|
|
||||||
.with_io(SERVER_ADDRESS)
|
|
||||||
.unwrap()
|
|
||||||
.with_tls((
|
|
||||||
Path::new("certificates/cert.pem"),
|
|
||||||
Path::new("certificates/key.pem"),
|
|
||||||
))
|
|
||||||
.unwrap()
|
|
||||||
.start()
|
|
||||||
.unwrap();
|
|
||||||
while let Some(mut connection) = server.accept().await {
|
|
||||||
println!(
|
|
||||||
"Server Name = {}",
|
|
||||||
connection.server_name().unwrap().unwrap().to_string()
|
|
||||||
);
|
|
||||||
while let Ok(Some(mut stream)) = connection.accept_bidirectional_stream().await {
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
String::from_utf8(stream.receive().await.unwrap().unwrap().to_vec()).unwrap()
|
|
||||||
);
|
|
||||||
stream
|
|
||||||
.send("Hi from Tahinli too".as_bytes().into())
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn client() {
|
|
||||||
let client = Client::builder()
|
|
||||||
.with_io("127.0.0.1:0")
|
|
||||||
.unwrap()
|
|
||||||
.with_tls(Path::new("certificates/cert.pem"))
|
|
||||||
.unwrap()
|
|
||||||
.start()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
println!("Client Address = {}", client.local_addr().unwrap());
|
|
||||||
let connect =
|
|
||||||
Connect::new(SERVER_ADDRESS.parse::<SocketAddr>().unwrap()).with_server_name("localhost");
|
|
||||||
let mut connection = match client.connect(connect).await {
|
|
||||||
Ok(connection) => connection,
|
|
||||||
Err(err_val) => {
|
|
||||||
eprintln!("Client Connection | {}", err_val);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
connection.keep_alive(true).unwrap();
|
|
||||||
|
|
||||||
let stream = connection.open_bidirectional_stream().await.unwrap();
|
|
||||||
let (mut receive_stream, mut send_stream) = stream.split();
|
|
||||||
send_stream
|
|
||||||
.send("Hi from Tahinli".as_bytes().into())
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let received = receive_stream.receive().await.unwrap().unwrap();
|
|
||||||
println!("{}", String::from_utf8(received.to_vec()).unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
53
src/server.rs
Normal file
53
src/server.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use s2n_quic::Server;
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
|
use crate::ServerConfig;
|
||||||
|
|
||||||
|
pub async fn run<'a>(server_config: ServerConfig<'a>) {
|
||||||
|
let mut server = Server::builder()
|
||||||
|
.with_io(server_config.server_address)
|
||||||
|
.unwrap()
|
||||||
|
.with_tls((
|
||||||
|
Path::new("certificates/cert.pem"),
|
||||||
|
Path::new("certificates/key.pem"),
|
||||||
|
))
|
||||||
|
.unwrap()
|
||||||
|
.start()
|
||||||
|
.unwrap();
|
||||||
|
while let Some(mut connection) = server.accept().await {
|
||||||
|
println!(
|
||||||
|
"Server Name = {}",
|
||||||
|
connection.server_name().unwrap().unwrap().to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Client Address = {}",
|
||||||
|
connection.remote_addr().unwrap().to_string()
|
||||||
|
);
|
||||||
|
while let Ok(Some(mut stream)) = connection.accept_bidirectional_stream().await {
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
String::from_utf8(stream.receive().await.unwrap().unwrap().to_vec()).unwrap()
|
||||||
|
);
|
||||||
|
match stream.send("Hi from Tahinli too".as_bytes().into()).await {
|
||||||
|
Ok(_) => {
|
||||||
|
if let Err(err_val) = stream.flush().await {
|
||||||
|
eprintln!("Error: Flush | {}", err_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err_val) => eprintln!("Error: Send | {}", err_val),
|
||||||
|
}
|
||||||
|
if let Err(err_val) = stream.close().await {
|
||||||
|
eprintln!("Error: Stream Close | {}", err_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err_val) = stream.shutdown().await {
|
||||||
|
eprintln!("Error: Stream Shutdown | {}", err_val);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
0
src/voice.rs
Normal file
0
src/voice.rs
Normal file
Loading…
Add table
Add a link
Reference in a new issue