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
|
@ -1,17 +1,22 @@
|
|||
use std::{net::SocketAddr, path::Path, sync::Arc};
|
||||
|
||||
use protocol::{BUFFER_LENGTH, Error};
|
||||
use s2n_quic::{Client, client::Connect};
|
||||
use s2n_quic::{
|
||||
Client,
|
||||
client::Connect,
|
||||
stream::{ReceiveStream, SendStream},
|
||||
};
|
||||
use tokio::{
|
||||
io::AsyncReadExt,
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
sync::{broadcast, oneshot},
|
||||
};
|
||||
|
||||
use crate::{ClientConfig, voice::play};
|
||||
|
||||
pub async fn connect(
|
||||
connection_signal: oneshot::Receiver<bool>,
|
||||
mut microphone_receiver: broadcast::Receiver<f32>,
|
||||
connection_stop_signal_receiver: oneshot::Receiver<bool>,
|
||||
is_connection_started_signal: oneshot::Sender<bool>,
|
||||
microphone_sender_for_producing_receiver: Arc<broadcast::Sender<f32>>,
|
||||
client_config: Arc<ClientConfig>,
|
||||
) -> Result<(), Error> {
|
||||
let client = Client::builder()
|
||||
|
@ -45,40 +50,91 @@ pub async fn connect(
|
|||
.open_bidirectional_stream()
|
||||
.await
|
||||
.map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?;
|
||||
let (mut receive_stream, mut send_stream) = stream.split();
|
||||
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_voice_data(receive_stream, speaker_sender));
|
||||
let send_voice_data_task = tokio::spawn(send_voice_data(
|
||||
send_stream,
|
||||
microphone_sender_for_producing_receiver,
|
||||
));
|
||||
|
||||
let (speaker_sender, speaker_receiver) = broadcast::channel::<f32>(BUFFER_LENGTH);
|
||||
|
||||
let (spearker_stop_signal_sender, speaker_stop_signal_receiver) = oneshot::channel::<bool>();
|
||||
|
||||
let play_task = tokio::spawn(play(speaker_receiver, speaker_stop_signal_receiver));
|
||||
let receive_task = tokio::spawn(async move {
|
||||
while let Ok(data) = receive_stream.read_f32_le().await {
|
||||
speaker_sender
|
||||
.send(data)
|
||||
.map_err(|err_val| Error::Signal(err_val.to_string()))
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
let send_task = tokio::spawn(async move {
|
||||
while let Ok(data) = microphone_receiver.recv().await {
|
||||
send_stream
|
||||
.send(data.to_le_bytes().to_vec().into())
|
||||
.await
|
||||
.map_err(|err_val| Error::Send(err_val.to_string()))
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
if let Ok(_) = connection_signal.await {
|
||||
println!("Connection Closing");
|
||||
if let Err(err_val) = is_connection_started_signal.send(true) {
|
||||
eprintln!(
|
||||
"Error: Is Connection Started | Local Channel | Send | {}",
|
||||
err_val
|
||||
);
|
||||
}
|
||||
spearker_stop_signal_sender
|
||||
.send(true)
|
||||
.map_err(|err_val| Error::Signal(err_val.to_string()))?;
|
||||
|
||||
send_task.abort();
|
||||
receive_task.abort();
|
||||
play_task.abort();
|
||||
if let Err(err_val) = connection_stop_signal_receiver.await {
|
||||
eprintln!(
|
||||
"Error: Connection Stop Signal | Local Channel | Receive | {}",
|
||||
err_val
|
||||
);
|
||||
}
|
||||
|
||||
if let Err(err_val) = speaker_stop_signal_sender.send(true) {
|
||||
eprintln!(
|
||||
"Error: Speaker Stop Signal | Local Channel | 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_voice_data(
|
||||
mut send_stream: SendStream,
|
||||
microphone_sender_for_producing_receiver: Arc<broadcast::Sender<f32>>,
|
||||
) {
|
||||
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 | {}", err_val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(err_val) => {
|
||||
eprintln!(
|
||||
"Error: Receive from Microphone | Local Channel | {}",
|
||||
err_val
|
||||
);
|
||||
match err_val {
|
||||
broadcast::error::RecvError::Closed => break,
|
||||
broadcast::error::RecvError::Lagged(_) => {
|
||||
microphone_receiver = microphone_receiver.resubscribe()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn receive_voice_data(
|
||||
mut receive_stream: ReceiveStream,
|
||||
speaker_sender: broadcast::Sender<f32>,
|
||||
) {
|
||||
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 Channel | {}", err_val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(err_val) => {
|
||||
eprintln!("Error: Receive Data | {}", err_val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue