use std::{net::SocketAddr, path::Path, sync::Arc}; use protocol::{BUFFER_LENGTH, Error}; use s2n_quic::{ Client, client::Connect, stream::{ReceiveStream, SendStream}, }; use tokio::{ io::{AsyncReadExt, AsyncWriteExt}, sync::{broadcast, oneshot}, }; use crate::{ClientConfig, voice::play}; pub async fn connect( connection_stop_signal_receiver: oneshot::Receiver, is_connection_started_signal: oneshot::Sender, microphone_sender_for_producing_receiver: Arc>, client_config: Arc, ) -> Result<(), Error> { let client = Client::builder() .with_io("0:0") .map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))? .with_tls(Path::new(&client_config.certificate_path)) .map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))? .start() .map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?; println!("Client Address = {}", client.local_addr().unwrap()); let connect = Connect::new( client_config .server_address .parse::() .map_err(|inner| Error::Connection(inner.to_string()))?, ) .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 Err(Error::Connection(err_val.to_string())); } }; connection .keep_alive(true) .map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?; let stream = connection .open_bidirectional_stream() .await .map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?; let (receive_stream, send_stream) = stream.split(); let (speaker_sender, speaker_receiver) = broadcast::channel(BUFFER_LENGTH); let (speaker_stop_signal_sender, speaker_stop_signal_receiver) = oneshot::channel(); tokio::spawn(play(speaker_receiver, speaker_stop_signal_receiver)); let receive_voice_data_task = tokio::spawn(receive_audio_data(receive_stream, speaker_sender)); let send_voice_data_task = tokio::spawn(send_audio_data( send_stream, microphone_sender_for_producing_receiver, )); if let Err(err_val) = is_connection_started_signal.send(true) { eprintln!("Error: Is Connection Started | Local | Send | {}", err_val); } if let Err(err_val) = connection_stop_signal_receiver.await { eprintln!( "Error: Connection Stop Signal | Local | Receive | {}", err_val ); } if let Err(err_val) = speaker_stop_signal_sender.send(true) { eprintln!("Error: Speaker Stop Signal | Local | Send | {}", err_val); } println!("Connection Is Closing"); receive_voice_data_task.abort(); send_voice_data_task.abort(); println!("Connection Is Closed"); Ok(()) } async fn send_audio_data( mut send_stream: SendStream, microphone_sender_for_producing_receiver: Arc>, ) { let mut microphone_receiver = microphone_sender_for_producing_receiver.subscribe(); loop { match microphone_receiver.recv().await { Ok(microphone_data) => { if let Err(err_val) = send_stream.write_f32(microphone_data).await { eprintln!("Error: Send Microphone Data | Remote | {}", err_val); break; } } Err(err_val) => { eprintln!("Error: Receive from Microphone | Local | {}", err_val); match err_val { broadcast::error::RecvError::Closed => break, broadcast::error::RecvError::Lagged(_) => { microphone_receiver = microphone_receiver.resubscribe() } } } } } } async fn receive_audio_data( mut receive_stream: ReceiveStream, speaker_sender: broadcast::Sender, ) { loop { match receive_stream.read_f32().await { Ok(received_data) => { if let Err(err_val) = speaker_sender.send(received_data) { eprintln!("Error: Send to Speaker | Local | {}", err_val); break; } } Err(err_val) => { eprintln!("Error: Receive Audio Data | Remote | {}", err_val); break; } } } }