Skip to content

Commit 53ced47

Browse files
committed
Update control api
Signed-off-by: Fabrice Desclaux <fabrice.desclaux@cea.fr>
1 parent db095c2 commit 53ced47

File tree

4 files changed

+93
-22
lines changed

4 files changed

+93
-22
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sanzu/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ rustls-pemfile = "1.0"
3535
sanzu-common = { path="../sanzu-common", default-features = false}
3636
serde = { version = "1.0", features = ["derive"] }
3737
serde_derive = "1.0"
38+
serde_json = "1.0"
3839
spin_sleep = "1.1"
3940
toml = "0.7"
4041
dbus = { version = "0.9", optional = true }

sanzu/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#[macro_use]
22
extern crate log;
33

4-
#[cfg(windows)]
54
#[macro_use]
65
extern crate lazy_static;
76

sanzu/src/server.rs

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@ use sanzu_common::{
1414
ReadWrite, Tunnel,
1515
};
1616

17+
use serde::{Deserialize, Serialize};
18+
1719
use spin_sleep::LoopHelper;
1820
use std::{
21+
io::{self, BufRead, Write},
1922
net::{self, IpAddr, TcpListener},
23+
sync::Mutex,
2024
time::Instant,
2125
};
2226

2327
#[cfg(unix)]
2428
use std::{
25-
sync::mpsc::channel,
29+
sync::mpsc::{channel, Sender},
2630
thread::{self},
2731
};
2832

@@ -47,6 +51,21 @@ use crate::server_x11::init_x11rb;
4751
#[cfg(windows)]
4852
use crate::server_windows::init_win;
4953

54+
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
55+
struct ServerStats {
56+
fps: u64,
57+
frame_time: u64,
58+
grab: u64,
59+
enc: u64,
60+
send: u64,
61+
recv: u64,
62+
size: (u16, u16),
63+
}
64+
65+
lazy_static! {
66+
static ref SERVER_STATS: Mutex<ServerStats> = Mutex::new(ServerStats::default());
67+
}
68+
5069
/// Tls auth / Kerberos Auth
5170
fn auth_client(
5271
config_tls: &ConfigTls,
@@ -97,6 +116,56 @@ fn auth_client(
97116
Ok((tls_conn, username))
98117
}
99118

119+
/// Handle control api
120+
/// restart => restart encoder
121+
/// stats => send encoding stats
122+
fn control_api(control_path: &str, control_sender: Sender<()>) {
123+
let pid = std::process::id();
124+
let control_path = control_path.replace("%PID%", &format!("{pid}"));
125+
// Try to remove path first
126+
let _ = std::fs::remove_file(&control_path);
127+
let listener = std::os::unix::net::UnixListener::bind(&control_path)
128+
.unwrap_or_else(|_| panic!("Cannot bind {:?}", control_path));
129+
loop {
130+
let (mut client, addr) = listener.accept().expect("Error in UnixListener accept");
131+
info!("Client {:?}", addr);
132+
let control_sender_cp = control_sender.clone();
133+
thread::spawn(move || {
134+
let mut command = String::new();
135+
if let Ok(length) = io::BufReader::new(&mut client).read_line(&mut command) {
136+
info!("Command: {:?} {}", command, length);
137+
match command.trim_end() {
138+
"restart" => {
139+
info!("Restart encoder requested");
140+
control_sender_cp.send(()).expect("Cannot send control");
141+
if client.write_all("Ok".as_bytes()).is_err() {
142+
warn!("Cannot send ok");
143+
}
144+
}
145+
"stats" => {
146+
info!("Stats requested");
147+
let stats = SERVER_STATS.lock().unwrap().clone();
148+
149+
if let Ok(stats_str) = serde_json::to_string(&stats) {
150+
if client.write_all(stats_str.as_bytes()).is_err() {
151+
warn!("Cannot send stat");
152+
}
153+
} else {
154+
warn!("Cannot generate stats");
155+
}
156+
}
157+
_ => {
158+
error!("Unknown command");
159+
if client.write_all("Unknown command".as_bytes()).is_err() {
160+
warn!("Cannot send stat");
161+
}
162+
}
163+
}
164+
}
165+
});
166+
}
167+
}
168+
100169
/// Exec main loop
101170
///
102171
pub fn run(config: &ConfigServer, arguments: &ArgumentsSrv) -> Result<()> {
@@ -374,34 +443,18 @@ pub fn run_server(config: &ConfigServer, arguments: &ArgumentsSrv) -> Result<()>
374443
let mut loop_helper = LoopHelper::builder().build_with_target_rate(config.video.max_fps as f64); // limit FPS if possible
375444

376445
let mut new_size = None;
377-
let mut cur_size = None;
446+
let (width, height) = server_info.size();
447+
let mut cur_size = Some((width as u32, height as u32));
378448

379449
// Do socket control
380450
#[cfg(unix)]
381451
let (control_sender, control_receiver) = channel();
382452
#[cfg(unix)]
383453
{
384-
let control_path = config
385-
.video
386-
.control_path
387-
.as_ref()
388-
.map(|path| path.to_owned());
389-
if let Some(control_path) = control_path {
454+
if let Some(control_path) = config.video.control_path.as_ref().cloned() {
390455
info!("Listening on control path {:?}", control_path);
391456
thread::spawn(move || {
392-
let pid = std::process::id();
393-
let control_path = control_path.replace("%PID%", &format!("{pid}"));
394-
// Try to remove path first
395-
let _ = std::fs::remove_file(&control_path);
396-
let listener = std::os::unix::net::UnixListener::bind(&control_path)
397-
.unwrap_or_else(|_| panic!("Cannot bind {:?}", control_path));
398-
loop {
399-
let (_, addr) = listener.accept().expect("Error in UnixListener accept");
400-
info!("Client {:?}", addr);
401-
control_sender
402-
.send("test".to_owned())
403-
.expect("Cannot send control");
404-
}
457+
control_api(&control_path.clone(), control_sender);
405458
});
406459
}
407460
}
@@ -563,6 +616,23 @@ pub fn run_server(config: &ConfigServer, arguments: &ArgumentsSrv) -> Result<()>
563616
);
564617
debug!("{}", msg);
565618
msg_stats = msg;
619+
let fps = match frame_time_micro as u64 {
620+
0 => 0,
621+
micros => 1_000_000 / micros,
622+
};
623+
let size = match cur_size.as_ref() {
624+
Some((width, height)) => (*width as u16, *height as u16),
625+
None => (0, 0),
626+
};
627+
*SERVER_STATS.lock().unwrap() = ServerStats {
628+
fps,
629+
frame_time: (time_start - prev_time_start).as_millis() as u64,
630+
grab: (time_grab - time_start).as_millis() as u64,
631+
enc: (time_encode - time_event).as_millis() as u64,
632+
send: (time_send - time_sound).as_millis() as u64,
633+
recv: (time_stop - time_send).as_millis() as u64,
634+
size,
635+
};
566636

567637
prev_time_start = time_start;
568638
loop_helper.loop_sleep(); // sleeps to acheive target FPS rate

0 commit comments

Comments
 (0)