phase 1
This commit is contained in:
74
media/server/src/main.rs
Normal file
74
media/server/src/main.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
use anyhow::Result;
|
||||
use cht_common::protocol::{self, ControlMessage, PacketType};
|
||||
use tokio::io::BufReader;
|
||||
use tokio::net::TcpListener;
|
||||
use tracing::{error, info};
|
||||
|
||||
const LISTEN_ADDR: &str = "0.0.0.0:4444";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
cht_common::logging::init("server");
|
||||
|
||||
let listener = TcpListener::bind(LISTEN_ADDR).await?;
|
||||
info!("Server listening on {LISTEN_ADDR}");
|
||||
|
||||
loop {
|
||||
let (stream, addr) = listener.accept().await?;
|
||||
info!("Client connected from {addr}");
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = handle_client(stream).await {
|
||||
error!("Client {addr} error: {e:#}");
|
||||
}
|
||||
info!("Client {addr} disconnected");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_client(stream: tokio::net::TcpStream) -> Result<()> {
|
||||
let mut reader = BufReader::new(stream);
|
||||
let mut video_packets = 0u64;
|
||||
let mut audio_packets = 0u64;
|
||||
|
||||
loop {
|
||||
let packet = match protocol::read_packet(&mut reader).await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
// Any read error at the header boundary is a clean disconnect
|
||||
// (includes EOF from flush + shutdown)
|
||||
let msg = format!("{e:#}");
|
||||
if msg.contains("eof") || msg.contains("Eof")
|
||||
|| msg.contains("connection reset")
|
||||
|| msg.contains("broken pipe")
|
||||
{
|
||||
break;
|
||||
}
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
match packet.header.packet_type {
|
||||
PacketType::Video => {
|
||||
video_packets += 1;
|
||||
if video_packets % 300 == 1 {
|
||||
info!(
|
||||
"video: {video_packets} packets, ts={}ms, keyframe={}",
|
||||
packet.header.timestamp_ns / 1_000_000,
|
||||
packet.header.is_keyframe(),
|
||||
);
|
||||
}
|
||||
}
|
||||
PacketType::Audio => {
|
||||
audio_packets += 1;
|
||||
}
|
||||
PacketType::Control => {
|
||||
let ctrl = ControlMessage::from_payload(&packet.payload)?;
|
||||
info!("control: {ctrl:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("Session totals: {video_packets} video, {audio_packets} audio packets");
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user