feat: ✨ talk locally and listen from server
This commit is contained in:
parent
d930888abb
commit
1451e9ccfc
9 changed files with 320 additions and 80 deletions
|
@ -9,3 +9,4 @@ serde = { workspace = true }
|
|||
serde_json = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
s2n-quic = { workspace = true }
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
pub mod stream;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ServerConfig {
|
||||
pub struct ServerConfig {
|
||||
certificate_path: String,
|
||||
certificate_key_path: String,
|
||||
server_address: String,
|
||||
}
|
||||
|
||||
impl ServerConfig {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
certificate_path: "./server/certificates/cert.pem".to_string(),
|
||||
certificate_key_path: "./server/certificates/key.pem".to_string(),
|
||||
server_address: "127.0.0.1:4546".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use server::{ServerConfig, stream::start};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
println!("Hello, world!");
|
||||
let server_config = ServerConfig::new();
|
||||
start(server_config).await;
|
||||
}
|
||||
|
|
105
server/src/stream.rs
Normal file
105
server/src/stream.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
use std::{path::Path, sync::LazyLock};
|
||||
|
||||
use protocol::BUFFER_LENGTH;
|
||||
use s2n_quic::{
|
||||
Connection, Server,
|
||||
stream::{ReceiveStream, SendStream},
|
||||
};
|
||||
use tokio::{
|
||||
io::AsyncReadExt,
|
||||
sync::{RwLock, broadcast},
|
||||
};
|
||||
|
||||
use crate::ServerConfig;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct User {
|
||||
sender_to_user: broadcast::Sender<f32>,
|
||||
}
|
||||
impl User {
|
||||
fn new() -> (Self, broadcast::Receiver<f32>) {
|
||||
let (sender, receiver) = broadcast::channel(BUFFER_LENGTH);
|
||||
let user = Self {
|
||||
sender_to_user: sender,
|
||||
};
|
||||
(user, receiver)
|
||||
}
|
||||
}
|
||||
|
||||
static ONLINE_USERS: LazyLock<RwLock<Vec<User>>> = LazyLock::new(|| RwLock::new(vec![]));
|
||||
|
||||
pub async fn start(server_config: ServerConfig) {
|
||||
let mut server = Server::builder()
|
||||
.with_io(server_config.server_address.as_str())
|
||||
.unwrap()
|
||||
.with_tls((
|
||||
Path::new(&server_config.certificate_path),
|
||||
Path::new(&server_config.certificate_key_path),
|
||||
))
|
||||
.unwrap()
|
||||
.start()
|
||||
.unwrap();
|
||||
|
||||
while let Some(connection) = server.accept().await {
|
||||
tokio::spawn(handle_client(connection));
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_client(mut connection: Connection) {
|
||||
println!(
|
||||
"Server Name = {}",
|
||||
connection.server_name().unwrap().unwrap().to_string()
|
||||
);
|
||||
|
||||
println!(
|
||||
"Client Address = {}",
|
||||
connection.remote_addr().unwrap().to_string()
|
||||
);
|
||||
|
||||
let stream = connection
|
||||
.accept_bidirectional_stream()
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let (receive_stream, send_stream) = stream.split();
|
||||
let (user, receiver) = User::new();
|
||||
ONLINE_USERS.write().await.push(user);
|
||||
tokio::spawn(receive_sound_data(receive_stream));
|
||||
tokio::spawn(send_sound_data(receiver, send_stream));
|
||||
}
|
||||
|
||||
async fn send_sound_data(mut receiver: broadcast::Receiver<f32>, mut send_stream: SendStream) {
|
||||
loop {
|
||||
match receiver.recv().await {
|
||||
Ok(received_data) => {
|
||||
if let Err(err_val) = send_stream
|
||||
.send(received_data.to_be_bytes().to_vec().into())
|
||||
.await
|
||||
{
|
||||
eprintln!("Error: Send Sound Data | {}", err_val);
|
||||
}
|
||||
}
|
||||
Err(err_val) => {
|
||||
eprintln!("Error: Receive Sound Data | Local Channel | {}", err_val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn receive_sound_data(mut receive_stream: ReceiveStream) {
|
||||
loop {
|
||||
match receive_stream.read_f32().await {
|
||||
Ok(received_data) => {
|
||||
for online_user in ONLINE_USERS.read().await.iter() {
|
||||
if let Err(err_val) = online_user.sender_to_user.send(received_data) {
|
||||
eprintln!("Error: Send Sound Data to All | {}", err_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err_val) => {
|
||||
eprintln!("Error: Receive Sound Data | {} ", err_val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue