tcp framing
This commit is contained in:
Generated
+82
@@ -283,6 +283,7 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"cpal",
|
"cpal",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
|
"futures",
|
||||||
"gag",
|
"gag",
|
||||||
"rand 0.10.2",
|
"rand 0.10.2",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
@@ -292,6 +293,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"shared",
|
"shared",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -645,12 +647,71 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-channel"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.34"
|
version = "0.3.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-sink"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.34"
|
version = "0.3.34"
|
||||||
@@ -663,8 +724,13 @@ version = "0.3.34"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"futures-macro",
|
||||||
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
@@ -1756,11 +1822,13 @@ name = "server"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"futures",
|
||||||
"rand 0.10.2",
|
"rand 0.10.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"shared",
|
"shared",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2106,6 +2174,20 @@ dependencies = [
|
|||||||
"syn 3.0.3",
|
"syn 3.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-util"
|
||||||
|
version = "0.7.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"libc",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "1.1.1+spec-1.1.0"
|
version = "1.1.1+spec-1.1.0"
|
||||||
|
|||||||
@@ -16,3 +16,5 @@ ropus = "0.12.18"
|
|||||||
ratatui = "0.30.2"
|
ratatui = "0.30.2"
|
||||||
crossterm = "0.29.0"
|
crossterm = "0.29.0"
|
||||||
gag = "1.0.0"
|
gag = "1.0.0"
|
||||||
|
tokio-util = { version = "0.7.19", features = ["codec"]}
|
||||||
|
futures = "0.3.34"
|
||||||
|
|||||||
+103
-98
@@ -1,12 +1,16 @@
|
|||||||
|
use futures::{SinkExt, StreamExt};
|
||||||
use ringbuf::{HeapRb, traits::Split};
|
use ringbuf::{HeapRb, traits::Split};
|
||||||
use ropus::Decoder;
|
use ropus::Decoder;
|
||||||
use shared::{ResponseStatus, TcpRequest, TcpResponse, TcpResponseData};
|
use shared::{ResponseStatus, TcpRequest, TcpResponse, TcpResponseData};
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncReadExt, AsyncWriteExt},
|
|
||||||
net::TcpStream,
|
net::TcpStream,
|
||||||
sync::broadcast::{Receiver, Sender},
|
sync::broadcast::{Receiver, Sender},
|
||||||
};
|
};
|
||||||
|
use tokio_util::{
|
||||||
|
bytes::Bytes,
|
||||||
|
codec::{Framed, LengthDelimitedCodec},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::models::{AudioControl, ClientEvent, ClientInfo};
|
use crate::models::{AudioControl, ClientEvent, ClientInfo};
|
||||||
|
|
||||||
@@ -21,99 +25,103 @@ pub async fn tcp_connection(
|
|||||||
info.server_address.clone()
|
info.server_address.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tcp_stream = TcpStream::connect(server_address)
|
let tcp_stream = TcpStream::connect(server_address)
|
||||||
.await
|
.await
|
||||||
.expect("failed to connect using tcp");
|
.expect("failed to connect using tcp");
|
||||||
|
|
||||||
let mut tcp_buf = [0u8; 4096];
|
let mut framed_tcp_stream = Framed::new(tcp_stream, LengthDelimitedCodec::new());
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
socket_result = tcp_stream.read(&mut tcp_buf) => {
|
frame_result = framed_tcp_stream.next() => {
|
||||||
|
match frame_result {
|
||||||
match socket_result {
|
None => {
|
||||||
Ok(0) => {
|
|
||||||
println!("server shut down");
|
println!("server shut down");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(n) => {
|
Some(Ok(bytes)) => {
|
||||||
let ssss = String::from_utf8(tcp_buf[0..n].to_vec()).unwrap();
|
match serde_json::from_slice::<TcpResponse>(&bytes) {
|
||||||
println!("json data: {}", ssss);
|
Ok(response) => {
|
||||||
|
println!("connection Ok: {}", response.status == ResponseStatus::Ok);
|
||||||
|
match response.data {
|
||||||
|
TcpResponseData::NewConnection { client_id } => {
|
||||||
|
let mut client_info_var = client_info.write().unwrap();
|
||||||
|
client_info_var.client_id = client_id;
|
||||||
|
client_info_var.connected = true;
|
||||||
|
println!("fetched client id: {}", client_id);
|
||||||
|
}
|
||||||
|
TcpResponseData::UserConnected { user_id } => {
|
||||||
|
println!("new user connected: {}", user_id);
|
||||||
|
}
|
||||||
|
TcpResponseData::UserDisconnected { user_id } => {
|
||||||
|
println!("user disconnected: {}", user_id);
|
||||||
|
}
|
||||||
|
TcpResponseData::AudioStreamsFullUpdate { audio_stream_info } => {
|
||||||
|
let mut producer_map = audio_control.active_input_audio_streams_producers.lock().unwrap();
|
||||||
|
producer_map.clear();
|
||||||
|
let mut consumer_map = audio_control.active_input_audio_streams_consumers.lock().unwrap();
|
||||||
|
consumer_map.clear();
|
||||||
|
|
||||||
match serde_json::from_slice::<TcpResponse>(&tcp_buf[0..n]) {
|
let mut encoder_map = audio_control.active_input_audio_streams_encoders.write().unwrap();
|
||||||
Ok(response) => {
|
encoder_map.clear();
|
||||||
println!("connection Ok: {}", response.status == ResponseStatus::Ok);
|
|
||||||
match response.data {
|
|
||||||
TcpResponseData::NewConnection { client_id } => {
|
|
||||||
let mut client_info_var = client_info.write().unwrap();
|
|
||||||
client_info_var.client_id = client_id;
|
|
||||||
client_info_var.connected = true;
|
|
||||||
println!("fetched client id: {}", client_id);
|
|
||||||
}
|
|
||||||
TcpResponseData::UserConnected { user_id } => {
|
|
||||||
println!("new user connected: {}", user_id);
|
|
||||||
}
|
|
||||||
TcpResponseData::UserDisconnected { user_id } => {
|
|
||||||
println!("user disconnected: {}", user_id);
|
|
||||||
}
|
|
||||||
TcpResponseData::AudioStreamsFullUpdate { audio_stream_info } => {
|
|
||||||
let mut producer_map = audio_control.active_input_audio_streams_producers.lock().unwrap();
|
|
||||||
producer_map.clear();
|
|
||||||
let mut consumer_map = audio_control.active_input_audio_streams_consumers.lock().unwrap();
|
|
||||||
consumer_map.clear();
|
|
||||||
|
|
||||||
let mut encoder_map = audio_control.active_input_audio_streams_encoders.write().unwrap();
|
let mut info_map = audio_control.active_input_audio_streams_info.write().unwrap();
|
||||||
encoder_map.clear();
|
info_map.clear();
|
||||||
|
|
||||||
let mut info_map = audio_control.active_input_audio_streams_info.write().unwrap();
|
|
||||||
info_map.clear();
|
|
||||||
|
|
||||||
|
for audio_stream in audio_stream_info {
|
||||||
|
let ring_buffer_ms = 150.0;
|
||||||
|
let ring_buffer_frames = (ring_buffer_ms / 1000.0) * audio_stream.sample_rate as f32;
|
||||||
|
let ring_buffer_samples = ring_buffer_frames as usize * audio_stream.channels as usize;
|
||||||
|
let ring_buffer_size = ring_buffer_samples;
|
||||||
|
let ring_buffer = HeapRb::<f32>::new(ring_buffer_size);
|
||||||
|
let (producer, consumer) = ring_buffer.split();
|
||||||
|
|
||||||
for audio_stream in audio_stream_info {
|
producer_map.insert(
|
||||||
let ring_buffer_ms = 150.0;
|
(audio_stream.client_id, audio_stream.stream_id),
|
||||||
let ring_buffer_frames = (ring_buffer_ms / 1000.0) * audio_stream.sample_rate as f32;
|
producer,
|
||||||
let ring_buffer_samples = ring_buffer_frames as usize * audio_stream.channels as usize;
|
);
|
||||||
let ring_buffer_size = ring_buffer_samples;
|
consumer_map.insert(
|
||||||
let ring_buffer = HeapRb::<f32>::new(ring_buffer_size);
|
(audio_stream.client_id, audio_stream.stream_id),
|
||||||
let (producer, consumer) = ring_buffer.split();
|
consumer,
|
||||||
|
);
|
||||||
|
|
||||||
producer_map.insert(
|
let channels: ropus::Channels = {
|
||||||
(audio_stream.client_id, audio_stream.stream_id),
|
if audio_stream.channels == 1 {
|
||||||
producer,
|
ropus::Channels::Mono
|
||||||
);
|
} else {
|
||||||
consumer_map.insert(
|
ropus::Channels::Stereo
|
||||||
(audio_stream.client_id, audio_stream.stream_id),
|
}
|
||||||
consumer,
|
};
|
||||||
);
|
|
||||||
|
|
||||||
let channels: ropus::Channels = {
|
let decoder = Decoder::new(audio_stream.sample_rate, channels).expect("failed to creat decoder");
|
||||||
if audio_stream.channels == 1 {
|
encoder_map.insert(
|
||||||
ropus::Channels::Mono
|
(audio_stream.client_id, audio_stream.stream_id),
|
||||||
} else {
|
Mutex::new(decoder),
|
||||||
ropus::Channels::Stereo
|
);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let decoder = Decoder::new(audio_stream.sample_rate, channels).expect("failed to creat decoder");
|
info_map.insert(
|
||||||
encoder_map.insert(
|
(audio_stream.client_id, audio_stream.stream_id),
|
||||||
(audio_stream.client_id, audio_stream.stream_id),
|
audio_stream,
|
||||||
Mutex::new(decoder),
|
);
|
||||||
);
|
}
|
||||||
|
println!("audio streams update");
|
||||||
info_map.insert(
|
}
|
||||||
(audio_stream.client_id, audio_stream.stream_id),
|
TcpResponseData::NewAudioStreamAccepted { audio_stream_id } => {
|
||||||
audio_stream,
|
let _ = global_event_tx.send(ClientEvent::NewAudioStreamAccepted(audio_stream_id));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
println!("audio streams update");
|
|
||||||
}
|
|
||||||
TcpResponseData::NewAudioStreamAccepted { audio_stream_id } => {
|
|
||||||
let _ = global_event_tx.send(ClientEvent::NewAudioStreamAccepted(audio_stream_id));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("parsing error: {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => eprintln!("failed to parse tcp packet: {}", e),}
|
}
|
||||||
},
|
Some(Err(e)) => {
|
||||||
Err(e) => eprintln!("failed to receive tcp packet: {}", e),
|
eprintln!("socket read error: {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event_result = global_event_rx.recv() => {
|
event_result = global_event_rx.recv() => {
|
||||||
@@ -121,34 +129,31 @@ pub async fn tcp_connection(
|
|||||||
Ok(event) => {
|
Ok(event) => {
|
||||||
match event {
|
match event {
|
||||||
ClientEvent::NewConnection => {
|
ClientEvent::NewConnection => {
|
||||||
let _ = tcp_stream
|
let request_json = serde_json::to_string(&TcpRequest {
|
||||||
.write_all(
|
client_id: 0,
|
||||||
serde_json::to_string(&TcpRequest {
|
data: shared::TcpRequestData::NewConnection,
|
||||||
client_id: 0,
|
})
|
||||||
data: shared::TcpRequestData::NewConnection,
|
.expect("failed to parse initial request");
|
||||||
})
|
|
||||||
.expect("failed to parse initial request")
|
let _ = framed_tcp_stream.send(Bytes::from(request_json))
|
||||||
.as_bytes(),
|
.await
|
||||||
)
|
.expect("failed to send initial message");
|
||||||
.await
|
|
||||||
.expect("failed to send initial message");
|
|
||||||
}
|
}
|
||||||
ClientEvent::NewAudioStreamRequest(audio_stream_info) => {
|
ClientEvent::NewAudioStreamRequest(audio_stream_info) => {
|
||||||
println!("new audio stream request");
|
println!("new audio stream request");
|
||||||
let session_client_id = client_info.read().unwrap().client_id;
|
let session_client_id = client_info.read().unwrap().client_id;
|
||||||
let _ = tcp_stream
|
|
||||||
.write_all(
|
let request_json = serde_json::to_string(&TcpRequest {
|
||||||
serde_json::to_string(&TcpRequest {
|
client_id: session_client_id,
|
||||||
client_id: session_client_id,
|
data: shared::TcpRequestData::NewAudioStream {
|
||||||
data: shared::TcpRequestData::NewAudioStream {
|
audio_stream_info
|
||||||
audio_stream_info
|
}
|
||||||
},
|
}).expect("failed to parse initial request");
|
||||||
})
|
|
||||||
.expect("failed to parse initial request")
|
let _ = framed_tcp_stream.send(Bytes::from(request_json))
|
||||||
.as_bytes(),
|
.await
|
||||||
)
|
.expect("failed to send initial message");
|
||||||
.await
|
|
||||||
.expect("failed to send initial message");
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,3 +10,5 @@ serde_json = "1.0.151"
|
|||||||
tokio = { version = "1.53.1", features = ["full"] }
|
tokio = { version = "1.53.1", features = ["full"] }
|
||||||
rand = "0.10.2"
|
rand = "0.10.2"
|
||||||
clap = { version = "4.6.6", features = ["derive"] }
|
clap = { version = "4.6.6", features = ["derive"] }
|
||||||
|
tokio-util = { version = "0.7.19", features = ["codec"]}
|
||||||
|
futures = "0.3.34"
|
||||||
|
|||||||
+99
-119
@@ -1,12 +1,14 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use futures::{SinkExt, StreamExt};
|
||||||
use shared::{AudioStreamInfo, ResponseStatus, TcpRequest, TcpRequestData, TcpResponse};
|
use shared::{AudioStreamInfo, ResponseStatus, TcpRequest, TcpRequestData, TcpResponse};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{collections::HashMap, net::SocketAddr};
|
use std::{collections::HashMap, net::SocketAddr};
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
|
||||||
use tokio::{
|
use tokio::{
|
||||||
net::{TcpListener, UdpSocket},
|
net::{TcpListener, UdpSocket},
|
||||||
sync::{RwLock, broadcast},
|
sync::{RwLock, broadcast},
|
||||||
};
|
};
|
||||||
|
use tokio_util::bytes::Bytes;
|
||||||
|
use tokio_util::codec::{Framed, LengthDelimitedCodec};
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(version, about)]
|
#[command(version, about)]
|
||||||
@@ -93,8 +95,9 @@ async fn main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let (mut tcp_stream, tcp_address) =
|
let (tcp_stream, tcp_address) = tcp_listener.accept().await.expect("failed to accept tcp");
|
||||||
tcp_listener.accept().await.expect("failed to accept tcp");
|
|
||||||
|
let mut framed_tcp_stream = Framed::new(tcp_stream, LengthDelimitedCodec::new());
|
||||||
|
|
||||||
let tcp_state = state.clone();
|
let tcp_state = state.clone();
|
||||||
|
|
||||||
@@ -103,88 +106,81 @@ async fn main() {
|
|||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let current_client_id: u32 = rand::random();
|
let current_client_id: u32 = rand::random();
|
||||||
let mut tcp_buf = [0; 4096];
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
socket_result = tcp_stream.read(&mut tcp_buf) => {
|
frame_result = framed_tcp_stream.next() => {
|
||||||
match socket_result {
|
match frame_result {
|
||||||
Ok(0) => {
|
None => {
|
||||||
let _ = global_event_tx_clone.send(ServerEvent::UserDisconnected(current_client_id));
|
let _ = global_event_tx_clone.send(ServerEvent::UserDisconnected(current_client_id));
|
||||||
println!("client disconnected: {}", tcp_address);
|
println!("client disconnected: {}", tcp_address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(n) => match serde_json::from_slice::<TcpRequest>(&tcp_buf[0..n]) {
|
Some(Ok(bytes)) => {
|
||||||
Ok(request) => match request.data {
|
match serde_json::from_slice::<TcpRequest>(&bytes) {
|
||||||
TcpRequestData::NewConnection => {
|
Ok(request) => match request.data {
|
||||||
tcp_state.write().await.insert(
|
TcpRequestData::NewConnection => {
|
||||||
current_client_id,
|
tcp_state.write().await.insert(
|
||||||
Client {
|
current_client_id,
|
||||||
udp_addr: None,
|
Client {
|
||||||
audio_streams: None,
|
udp_addr: None,
|
||||||
},
|
audio_streams: None,
|
||||||
);
|
},
|
||||||
|
);
|
||||||
|
|
||||||
println!("new client: {}, from: {}", current_client_id, tcp_address);
|
println!("new client: {}, from: {}", current_client_id, tcp_address);
|
||||||
let _ = tcp_stream
|
|
||||||
.write_all(
|
|
||||||
serde_json::to_string(&TcpResponse {
|
|
||||||
status: ResponseStatus::Ok,
|
|
||||||
data: shared::TcpResponseData::NewConnection {
|
|
||||||
client_id: current_client_id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.expect("failed to parse response json TcpRequestData::NewConnection")
|
|
||||||
.as_bytes(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let _ = global_event_tx_clone.send(ServerEvent::UserConnected(current_client_id));
|
let response_json = serde_json::to_string(&TcpResponse {
|
||||||
}
|
status: ResponseStatus::Ok,
|
||||||
TcpRequestData::NewAudioStream { audio_stream_info } => {
|
data: shared::TcpResponseData::NewConnection {
|
||||||
if let Some(client) = tcp_state.write().await.get_mut(¤t_client_id) {
|
client_id: current_client_id,
|
||||||
if let Some(audio_streams) = &mut client.audio_streams {
|
},
|
||||||
audio_streams.push(audio_stream_info);
|
}).expect("failed to serialize TcpRequestData::NewAudioStreamAccepted");
|
||||||
} else {
|
|
||||||
client.audio_streams = Some(vec![audio_stream_info]);
|
let _ = framed_tcp_stream.send(Bytes::from(response_json))
|
||||||
}
|
.await
|
||||||
|
.expect("failed to send message");
|
||||||
|
|
||||||
|
let _ = global_event_tx_clone.send(ServerEvent::UserConnected(current_client_id));
|
||||||
}
|
}
|
||||||
let _ = tcp_stream
|
TcpRequestData::NewAudioStream { audio_stream_info } => {
|
||||||
.write_all(
|
if let Some(client) = tcp_state.write().await.get_mut(¤t_client_id) {
|
||||||
serde_json::to_string(&TcpResponse {
|
if let Some(audio_streams) = &mut client.audio_streams {
|
||||||
status: ResponseStatus::Ok,
|
audio_streams.push(audio_stream_info.clone());
|
||||||
data: shared::TcpResponseData::NewAudioStreamAccepted {
|
} else {
|
||||||
audio_stream_id: audio_stream_info.stream_id,
|
client.audio_streams = Some(vec![audio_stream_info.clone()]);
|
||||||
},
|
}
|
||||||
})
|
}
|
||||||
.expect("failed to parse response json TcpRequestData::NewConnection")
|
|
||||||
.as_bytes(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
let response_json = serde_json::to_string(&TcpResponse {
|
||||||
}
|
status: ResponseStatus::Ok,
|
||||||
TcpRequestData::DropAudioStream { audio_stream_id } => {
|
data: shared::TcpResponseData::NewAudioStreamAccepted {
|
||||||
if let Some(client) = tcp_state.write().await.get_mut(¤t_client_id) {
|
audio_stream_id: audio_stream_info.stream_id,
|
||||||
if let Some(audio_streams) = &mut client.audio_streams {
|
},
|
||||||
let mut maybe_idx: Option<usize> = None;
|
}).expect("failed to serialize TcpRequestData::NewAudioStreamAccepted");
|
||||||
for (i, audio_stream) in audio_streams.iter_mut().enumerate() {
|
|
||||||
if audio_stream.stream_id == audio_stream_id {
|
let _ = framed_tcp_stream.send(Bytes::from(response_json)).await;
|
||||||
maybe_idx = Some(i);
|
|
||||||
|
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
||||||
|
}
|
||||||
|
TcpRequestData::DropAudioStream { audio_stream_id } => {
|
||||||
|
if let Some(client) = tcp_state.write().await.get_mut(¤t_client_id) {
|
||||||
|
if let Some(audio_streams) = &mut client.audio_streams {
|
||||||
|
if let Some(idx) = audio_streams.iter().position(|s| s.stream_id == audio_stream_id) {
|
||||||
|
audio_streams.remove(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(idx) = maybe_idx {
|
|
||||||
audio_streams.remove(idx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
||||||
}
|
}
|
||||||
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
},
|
||||||
}
|
Err(e) => eprintln!("failed to parse tcp packet: {}", e),
|
||||||
_ => eprintln!("i dont support other requests yet"),
|
}
|
||||||
},
|
}
|
||||||
Err(e) => eprintln!("failed to parse tcp packet: {}", e),
|
Some(Err(e)) => {
|
||||||
},
|
eprintln!("socket read error: {}", e);
|
||||||
Err(e) => eprintln!("failed to receive tcp packet: {}", e),
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event_result = global_event_rx.recv() => {
|
event_result = global_event_rx.recv() => {
|
||||||
@@ -193,36 +189,28 @@ async fn main() {
|
|||||||
match event {
|
match event {
|
||||||
ServerEvent::UserConnected(new_user_id) => {
|
ServerEvent::UserConnected(new_user_id) => {
|
||||||
if new_user_id != current_client_id {
|
if new_user_id != current_client_id {
|
||||||
let _ = tcp_stream
|
let response_json = serde_json::to_string(&TcpResponse {
|
||||||
.write_all(
|
status: ResponseStatus::Ok,
|
||||||
serde_json::to_string(&TcpResponse {
|
data: shared::TcpResponseData::UserConnected {
|
||||||
status: ResponseStatus::Ok,
|
user_id: new_user_id
|
||||||
data: shared::TcpResponseData::UserConnected {
|
},
|
||||||
user_id: new_user_id
|
}).expect("failed to serialize ServerEvent::UserConnected");
|
||||||
},
|
|
||||||
})
|
let _ = framed_tcp_stream.send(Bytes::from(response_json)).await;
|
||||||
.expect("failed to parse response json ServerEvent::UserConnected")
|
|
||||||
.as_bytes(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ServerEvent::UserDisconnected(user_id) => {
|
ServerEvent::UserDisconnected(user_id) => {
|
||||||
if user_id != current_client_id {
|
if user_id != current_client_id {
|
||||||
let _ = tcp_stream
|
let response_json = serde_json::to_string(&TcpResponse {
|
||||||
.write_all(
|
status: ResponseStatus::Ok,
|
||||||
serde_json::to_string(&TcpResponse {
|
data: shared::TcpResponseData::UserDisconnected {
|
||||||
status: ResponseStatus::Ok,
|
user_id: user_id
|
||||||
data: shared::TcpResponseData::UserDisconnected {
|
},
|
||||||
user_id: user_id
|
}).expect("failed to serialize ServerEvent::UserDisconnected");
|
||||||
},
|
|
||||||
})
|
let _ = framed_tcp_stream.send(Bytes::from(response_json)).await;
|
||||||
.expect("failed to parse response json ServerEvent::UserConnected")
|
|
||||||
.as_bytes(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
||||||
}
|
}
|
||||||
@@ -231,38 +219,30 @@ async fn main() {
|
|||||||
if current_client_id != id {
|
if current_client_id != id {
|
||||||
let clients = tcp_state.read().await;
|
let clients = tcp_state.read().await;
|
||||||
|
|
||||||
let _ = tcp_stream
|
let response_json = serde_json::to_string(&TcpResponse {
|
||||||
.write_all(
|
status: ResponseStatus::Ok,
|
||||||
serde_json::to_string(&TcpResponse {
|
data: shared::TcpResponseData::AudioStreamsFullUpdate {
|
||||||
status: ResponseStatus::Ok,
|
audio_stream_info: scrape_all_client_streams_info(&clients),
|
||||||
data: shared::TcpResponseData::AudioStreamsFullUpdate {
|
},
|
||||||
audio_stream_info: scrape_all_client_streams_info(&clients),
|
}).expect("failed to serialize ServerEvent::SendAllOtherStreams");
|
||||||
},
|
|
||||||
})
|
let _ = framed_tcp_stream.send(Bytes::from(response_json)).await;
|
||||||
.expect("failed to parse response json TcpRequestData::NewConnection")
|
|
||||||
.as_bytes(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ServerEvent::SendAllStreams => {
|
ServerEvent::SendAllStreams => {
|
||||||
let clients = tcp_state.read().await;
|
let clients = tcp_state.read().await;
|
||||||
|
|
||||||
let _ = tcp_stream
|
let response_json = serde_json::to_string(&TcpResponse {
|
||||||
.write_all(
|
status: ResponseStatus::Ok,
|
||||||
serde_json::to_string(&TcpResponse {
|
data: shared::TcpResponseData::AudioStreamsFullUpdate {
|
||||||
status: ResponseStatus::Ok,
|
audio_stream_info: scrape_all_client_streams_info(&clients),
|
||||||
data: shared::TcpResponseData::AudioStreamsFullUpdate {
|
},
|
||||||
audio_stream_info: scrape_all_client_streams_info(&clients),
|
}).expect("failed to serialize ServerEvent::SendAllStreams");
|
||||||
},
|
|
||||||
})
|
let _ = framed_tcp_stream.send(Bytes::from(response_json)).await;
|
||||||
.expect("failed to parse response json TcpRequestData::NewConnection")
|
|
||||||
.as_bytes(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("lkdahjsf");
|
println!("unhandled event");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user