tcp framing
This commit is contained in:
+99
-119
@@ -1,12 +1,14 @@
|
||||
use clap::Parser;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use shared::{AudioStreamInfo, ResponseStatus, TcpRequest, TcpRequestData, TcpResponse};
|
||||
use std::sync::Arc;
|
||||
use std::{collections::HashMap, net::SocketAddr};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::{
|
||||
net::{TcpListener, UdpSocket},
|
||||
sync::{RwLock, broadcast},
|
||||
};
|
||||
use tokio_util::bytes::Bytes;
|
||||
use tokio_util::codec::{Framed, LengthDelimitedCodec};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version, about)]
|
||||
@@ -93,8 +95,9 @@ async fn main() {
|
||||
});
|
||||
|
||||
loop {
|
||||
let (mut tcp_stream, tcp_address) =
|
||||
tcp_listener.accept().await.expect("failed to accept tcp");
|
||||
let (tcp_stream, tcp_address) = 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();
|
||||
|
||||
@@ -103,88 +106,81 @@ async fn main() {
|
||||
|
||||
tokio::spawn(async move {
|
||||
let current_client_id: u32 = rand::random();
|
||||
let mut tcp_buf = [0; 4096];
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
socket_result = tcp_stream.read(&mut tcp_buf) => {
|
||||
match socket_result {
|
||||
Ok(0) => {
|
||||
frame_result = framed_tcp_stream.next() => {
|
||||
match frame_result {
|
||||
None => {
|
||||
let _ = global_event_tx_clone.send(ServerEvent::UserDisconnected(current_client_id));
|
||||
println!("client disconnected: {}", tcp_address);
|
||||
break;
|
||||
}
|
||||
Ok(n) => match serde_json::from_slice::<TcpRequest>(&tcp_buf[0..n]) {
|
||||
Ok(request) => match request.data {
|
||||
TcpRequestData::NewConnection => {
|
||||
tcp_state.write().await.insert(
|
||||
current_client_id,
|
||||
Client {
|
||||
udp_addr: None,
|
||||
audio_streams: None,
|
||||
},
|
||||
);
|
||||
Some(Ok(bytes)) => {
|
||||
match serde_json::from_slice::<TcpRequest>(&bytes) {
|
||||
Ok(request) => match request.data {
|
||||
TcpRequestData::NewConnection => {
|
||||
tcp_state.write().await.insert(
|
||||
current_client_id,
|
||||
Client {
|
||||
udp_addr: None,
|
||||
audio_streams: None,
|
||||
},
|
||||
);
|
||||
|
||||
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;
|
||||
println!("new client: {}, from: {}", current_client_id, tcp_address);
|
||||
|
||||
let _ = global_event_tx_clone.send(ServerEvent::UserConnected(current_client_id));
|
||||
}
|
||||
TcpRequestData::NewAudioStream { audio_stream_info } => {
|
||||
if let Some(client) = tcp_state.write().await.get_mut(¤t_client_id) {
|
||||
if let Some(audio_streams) = &mut client.audio_streams {
|
||||
audio_streams.push(audio_stream_info);
|
||||
} else {
|
||||
client.audio_streams = Some(vec![audio_stream_info]);
|
||||
}
|
||||
let response_json = serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
data: shared::TcpResponseData::NewConnection {
|
||||
client_id: current_client_id,
|
||||
},
|
||||
}).expect("failed to serialize TcpRequestData::NewAudioStreamAccepted");
|
||||
|
||||
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
|
||||
.write_all(
|
||||
serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
data: shared::TcpResponseData::NewAudioStreamAccepted {
|
||||
audio_stream_id: audio_stream_info.stream_id,
|
||||
},
|
||||
})
|
||||
.expect("failed to parse response json TcpRequestData::NewConnection")
|
||||
.as_bytes(),
|
||||
)
|
||||
.await;
|
||||
TcpRequestData::NewAudioStream { audio_stream_info } => {
|
||||
if let Some(client) = tcp_state.write().await.get_mut(¤t_client_id) {
|
||||
if let Some(audio_streams) = &mut client.audio_streams {
|
||||
audio_streams.push(audio_stream_info.clone());
|
||||
} else {
|
||||
client.audio_streams = Some(vec![audio_stream_info.clone()]);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
let mut maybe_idx: Option<usize> = None;
|
||||
for (i, audio_stream) in audio_streams.iter_mut().enumerate() {
|
||||
if audio_stream.stream_id == audio_stream_id {
|
||||
maybe_idx = Some(i);
|
||||
let response_json = serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
data: shared::TcpResponseData::NewAudioStreamAccepted {
|
||||
audio_stream_id: audio_stream_info.stream_id,
|
||||
},
|
||||
}).expect("failed to serialize TcpRequestData::NewAudioStreamAccepted");
|
||||
|
||||
let _ = framed_tcp_stream.send(Bytes::from(response_json)).await;
|
||||
|
||||
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));
|
||||
}
|
||||
_ => eprintln!("i dont support other requests yet"),
|
||||
},
|
||||
Err(e) => eprintln!("failed to parse tcp packet: {}", e),
|
||||
},
|
||||
Err(e) => eprintln!("failed to receive tcp packet: {}", e),
|
||||
},
|
||||
Err(e) => eprintln!("failed to parse tcp packet: {}", e),
|
||||
}
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
eprintln!("socket read error: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
event_result = global_event_rx.recv() => {
|
||||
@@ -193,36 +189,28 @@ async fn main() {
|
||||
match event {
|
||||
ServerEvent::UserConnected(new_user_id) => {
|
||||
if new_user_id != current_client_id {
|
||||
let _ = tcp_stream
|
||||
.write_all(
|
||||
serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
data: shared::TcpResponseData::UserConnected {
|
||||
user_id: new_user_id
|
||||
},
|
||||
})
|
||||
.expect("failed to parse response json ServerEvent::UserConnected")
|
||||
.as_bytes(),
|
||||
)
|
||||
.await;
|
||||
let response_json = serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
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;
|
||||
|
||||
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
||||
}
|
||||
}
|
||||
ServerEvent::UserDisconnected(user_id) => {
|
||||
if user_id != current_client_id {
|
||||
let _ = tcp_stream
|
||||
.write_all(
|
||||
serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
data: shared::TcpResponseData::UserDisconnected {
|
||||
user_id: user_id
|
||||
},
|
||||
})
|
||||
.expect("failed to parse response json ServerEvent::UserConnected")
|
||||
.as_bytes(),
|
||||
)
|
||||
.await;
|
||||
let response_json = serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
data: shared::TcpResponseData::UserDisconnected {
|
||||
user_id: user_id
|
||||
},
|
||||
}).expect("failed to serialize ServerEvent::UserDisconnected");
|
||||
|
||||
let _ = framed_tcp_stream.send(Bytes::from(response_json)).await;
|
||||
|
||||
let _ = global_event_tx_clone.send(ServerEvent::SendAllOtherStreams(current_client_id));
|
||||
}
|
||||
@@ -231,38 +219,30 @@ async fn main() {
|
||||
if current_client_id != id {
|
||||
let clients = tcp_state.read().await;
|
||||
|
||||
let _ = tcp_stream
|
||||
.write_all(
|
||||
serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
data: shared::TcpResponseData::AudioStreamsFullUpdate {
|
||||
audio_stream_info: scrape_all_client_streams_info(&clients),
|
||||
},
|
||||
})
|
||||
.expect("failed to parse response json TcpRequestData::NewConnection")
|
||||
.as_bytes(),
|
||||
)
|
||||
.await;
|
||||
let response_json = serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
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;
|
||||
}
|
||||
}
|
||||
ServerEvent::SendAllStreams => {
|
||||
let clients = tcp_state.read().await;
|
||||
|
||||
let _ = tcp_stream
|
||||
.write_all(
|
||||
serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
data: shared::TcpResponseData::AudioStreamsFullUpdate {
|
||||
audio_stream_info: scrape_all_client_streams_info(&clients),
|
||||
},
|
||||
})
|
||||
.expect("failed to parse response json TcpRequestData::NewConnection")
|
||||
.as_bytes(),
|
||||
)
|
||||
.await;
|
||||
let response_json = serde_json::to_string(&TcpResponse {
|
||||
status: ResponseStatus::Ok,
|
||||
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;
|
||||
}
|
||||
_ => {
|
||||
println!("lkdahjsf");
|
||||
println!("unhandled event");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user