2025-05-15 23:19:39 +03:00
|
|
|
use std::{net::SocketAddr, path::Path, sync::Arc};
|
2025-05-14 23:43:35 +03:00
|
|
|
|
2025-05-20 05:44:00 +03:00
|
|
|
use protocol::Error;
|
2025-05-17 05:05:33 +03:00
|
|
|
use s2n_quic::{
|
|
|
|
Client,
|
|
|
|
client::Connect,
|
|
|
|
stream::{ReceiveStream, SendStream},
|
|
|
|
};
|
2025-05-14 23:43:35 +03:00
|
|
|
use tokio::{
|
2025-05-17 05:05:33 +03:00
|
|
|
io::{AsyncReadExt, AsyncWriteExt},
|
2025-05-14 23:43:35 +03:00
|
|
|
sync::{broadcast, oneshot},
|
2025-05-21 22:33:04 +03:00
|
|
|
task::JoinHandle,
|
2025-05-14 23:43:35 +03:00
|
|
|
};
|
|
|
|
|
2025-05-20 05:44:00 +03:00
|
|
|
use crate::{ClientConfig, SPEAKER_BUFFER_LENGHT, voice::play};
|
2025-05-14 23:43:35 +03:00
|
|
|
|
2025-05-21 22:33:04 +03:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ConnectReturn {
|
|
|
|
play_audio_stop_signal_sender: oneshot::Sender<bool>,
|
|
|
|
send_audio_task: JoinHandle<()>,
|
|
|
|
receive_audio_task: JoinHandle<()>,
|
|
|
|
}
|
|
|
|
|
2025-05-15 23:19:39 +03:00
|
|
|
pub async fn connect(
|
2025-05-21 22:33:04 +03:00
|
|
|
microphone_receiver: broadcast::Receiver<f32>,
|
2025-05-15 23:19:39 +03:00
|
|
|
client_config: Arc<ClientConfig>,
|
2025-05-21 22:33:04 +03:00
|
|
|
) -> Result<ConnectReturn, Error> {
|
2025-05-14 23:43:35 +03:00
|
|
|
let client = Client::builder()
|
|
|
|
.with_io("0:0")
|
2025-05-15 23:19:39 +03:00
|
|
|
.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()))?
|
2025-05-14 23:43:35 +03:00
|
|
|
.start()
|
2025-05-15 23:19:39 +03:00
|
|
|
.map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?;
|
2025-05-14 23:43:35 +03:00
|
|
|
|
|
|
|
println!("Client Address = {}", client.local_addr().unwrap());
|
2025-05-15 23:19:39 +03:00
|
|
|
let connect = Connect::new(
|
|
|
|
client_config
|
|
|
|
.server_address
|
|
|
|
.parse::<SocketAddr>()
|
|
|
|
.map_err(|inner| Error::Connection(inner.to_string()))?,
|
|
|
|
)
|
|
|
|
.with_server_name("localhost");
|
2025-05-14 23:43:35 +03:00
|
|
|
let mut connection = match client.connect(connect).await {
|
|
|
|
Ok(connection) => connection,
|
|
|
|
Err(err_val) => {
|
|
|
|
eprintln!("Error: Client Connection | {}", err_val);
|
2025-05-15 23:19:39 +03:00
|
|
|
return Err(Error::Connection(err_val.to_string()));
|
2025-05-14 23:43:35 +03:00
|
|
|
}
|
|
|
|
};
|
2025-05-15 23:19:39 +03:00
|
|
|
connection
|
|
|
|
.keep_alive(true)
|
|
|
|
.map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?;
|
2025-05-14 23:43:35 +03:00
|
|
|
|
2025-05-15 23:19:39 +03:00
|
|
|
let stream = connection
|
|
|
|
.open_bidirectional_stream()
|
|
|
|
.await
|
|
|
|
.map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?;
|
2025-05-21 22:33:04 +03:00
|
|
|
|
2025-05-17 05:05:33 +03:00
|
|
|
let (receive_stream, send_stream) = stream.split();
|
2025-05-21 22:33:04 +03:00
|
|
|
|
2025-05-20 05:44:00 +03:00
|
|
|
let (speaker_sender, speaker_receiver) = broadcast::channel(SPEAKER_BUFFER_LENGHT);
|
2025-05-21 22:33:04 +03:00
|
|
|
let (play_audio_stop_signal_sender, play_audio_stop_signal_receiver) = oneshot::channel();
|
2025-05-14 23:43:35 +03:00
|
|
|
|
2025-05-21 22:33:04 +03:00
|
|
|
tokio::spawn(play(speaker_receiver, play_audio_stop_signal_receiver));
|
|
|
|
let receive_audio_task = tokio::spawn(receive_audio_data(receive_stream, speaker_sender));
|
|
|
|
let send_audio_task = tokio::spawn(send_audio_data(send_stream, microphone_receiver));
|
|
|
|
|
|
|
|
Ok(ConnectReturn {
|
|
|
|
play_audio_stop_signal_sender,
|
|
|
|
send_audio_task,
|
|
|
|
receive_audio_task,
|
|
|
|
})
|
|
|
|
}
|
2025-05-14 23:43:35 +03:00
|
|
|
|
2025-05-21 22:33:04 +03:00
|
|
|
pub async fn disconnect_watcher(
|
|
|
|
connection_stop_receiver: oneshot::Receiver<bool>,
|
|
|
|
connection_return: ConnectReturn,
|
|
|
|
) {
|
|
|
|
if let Err(err_val) = connection_stop_receiver.await {
|
2025-05-17 05:05:33 +03:00
|
|
|
eprintln!(
|
2025-05-21 22:33:04 +03:00
|
|
|
"Error: Receive Connection Stop Signal | Local | {}",
|
2025-05-17 05:05:33 +03:00
|
|
|
err_val
|
|
|
|
);
|
|
|
|
}
|
2025-05-14 23:43:35 +03:00
|
|
|
|
2025-05-21 22:33:04 +03:00
|
|
|
connection_return.send_audio_task.abort();
|
|
|
|
connection_return.receive_audio_task.abort();
|
|
|
|
if let Err(err_val) = connection_return.play_audio_stop_signal_sender.send(true) {
|
|
|
|
eprintln!("Error: Send Play Audio Stop Signal | Local | {}", err_val);
|
2025-05-15 23:19:39 +03:00
|
|
|
}
|
2025-05-14 23:43:35 +03:00
|
|
|
}
|
2025-05-17 05:05:33 +03:00
|
|
|
|
2025-05-20 00:59:34 +03:00
|
|
|
async fn send_audio_data(
|
2025-05-17 05:05:33 +03:00
|
|
|
mut send_stream: SendStream,
|
2025-05-21 22:33:04 +03:00
|
|
|
old_microphone_receiver: broadcast::Receiver<f32>,
|
2025-05-17 05:05:33 +03:00
|
|
|
) {
|
2025-05-21 22:33:04 +03:00
|
|
|
let mut microphone_receiver = old_microphone_receiver.resubscribe();
|
|
|
|
drop(old_microphone_receiver);
|
2025-05-17 05:05:33 +03:00
|
|
|
loop {
|
|
|
|
match microphone_receiver.recv().await {
|
|
|
|
Ok(microphone_data) => {
|
|
|
|
if let Err(err_val) = send_stream.write_f32(microphone_data).await {
|
2025-05-20 00:59:34 +03:00
|
|
|
eprintln!("Error: Send Microphone Data | Remote | {}", err_val);
|
2025-05-21 22:33:04 +03:00
|
|
|
todo!("GUI Status: Disconnect");
|
|
|
|
// break;
|
2025-05-17 05:05:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err_val) => {
|
2025-05-20 00:59:34 +03:00
|
|
|
eprintln!("Error: Receive from Microphone | Local | {}", err_val);
|
2025-05-17 05:05:33 +03:00
|
|
|
match err_val {
|
|
|
|
broadcast::error::RecvError::Closed => break,
|
|
|
|
broadcast::error::RecvError::Lagged(_) => {
|
|
|
|
microphone_receiver = microphone_receiver.resubscribe()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-05-20 00:59:34 +03:00
|
|
|
async fn receive_audio_data(
|
2025-05-17 05:05:33 +03:00
|
|
|
mut receive_stream: ReceiveStream,
|
|
|
|
speaker_sender: broadcast::Sender<f32>,
|
|
|
|
) {
|
|
|
|
loop {
|
|
|
|
match receive_stream.read_f32().await {
|
|
|
|
Ok(received_data) => {
|
2025-05-21 22:33:04 +03:00
|
|
|
// error only happens if there is no receiver, think about it
|
2025-05-17 05:05:33 +03:00
|
|
|
if let Err(err_val) = speaker_sender.send(received_data) {
|
2025-05-20 00:59:34 +03:00
|
|
|
eprintln!("Error: Send to Speaker | Local | {}", err_val);
|
2025-05-17 05:05:33 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err_val) => {
|
2025-05-20 00:59:34 +03:00
|
|
|
eprintln!("Error: Receive Audio Data | Remote | {}", err_val);
|
2025-05-21 22:33:04 +03:00
|
|
|
todo!("GUI Status Disconnect");
|
|
|
|
// break;
|
2025-05-17 05:05:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|