Skip to content

Commit 698a8a2

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

File tree

4 files changed

+96
-22
lines changed

4 files changed

+96
-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: 94 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,21 @@ use sanzu_common::{
1414
ReadWrite, Tunnel,
1515
};
1616

17+
use serde::{Deserialize, Serialize};
18+
1719
use spin_sleep::LoopHelper;
1820
use std::{
1921
net::{self, IpAddr, TcpListener},
22+
sync::Mutex,
2023
time::Instant,
2124
};
2225

26+
#[cfg(unix)]
27+
use std::io::{self, BufRead, Write};
28+
2329
#[cfg(unix)]
2430
use std::{
25-
sync::mpsc::channel,
31+
sync::mpsc::{channel, Sender},
2632
thread::{self},
2733
};
2834

@@ -47,6 +53,21 @@ use crate::server_x11::init_x11rb;
4753
#[cfg(windows)]
4854
use crate::server_windows::init_win;
4955

56+
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
57+
struct ServerStats {
58+
fps: u64,
59+
frame_time: u64,
60+
grab: u64,
61+
enc: u64,
62+
send: u64,
63+
recv: u64,
64+
size: (u16, u16),
65+
}
66+
67+
lazy_static! {
68+
static ref SERVER_STATS: Mutex<ServerStats> = Mutex::new(ServerStats::default());
69+
}
70+
5071
/// Tls auth / Kerberos Auth
5172
fn auth_client(
5273
config_tls: &ConfigTls,
@@ -97,6 +118,57 @@ fn auth_client(
97118
Ok((tls_conn, username))
98119
}
99120

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

376448
let mut new_size = None;
377-
let mut cur_size = None;
449+
let (width, height) = server_info.size();
450+
let mut cur_size = Some((width as u32, height as u32));
378451

379452
// Do socket control
380453
#[cfg(unix)]
381454
let (control_sender, control_receiver) = channel();
382455
#[cfg(unix)]
383456
{
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 {
457+
if let Some(control_path) = config.video.control_path.as_ref().cloned() {
390458
info!("Listening on control path {:?}", control_path);
391459
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-
}
460+
control_api(&control_path.clone(), control_sender);
405461
});
406462
}
407463
}
@@ -563,6 +619,23 @@ pub fn run_server(config: &ConfigServer, arguments: &ArgumentsSrv) -> Result<()>
563619
);
564620
debug!("{}", msg);
565621
msg_stats = msg;
622+
let fps = match frame_time_micro as u64 {
623+
0 => 0,
624+
micros => 1_000_000 / micros,
625+
};
626+
let size = match cur_size.as_ref() {
627+
Some((width, height)) => (*width as u16, *height as u16),
628+
None => (0, 0),
629+
};
630+
*SERVER_STATS.lock().unwrap() = ServerStats {
631+
fps,
632+
frame_time: (time_start - prev_time_start).as_millis() as u64,
633+
grab: (time_grab - time_start).as_millis() as u64,
634+
enc: (time_encode - time_event).as_millis() as u64,
635+
send: (time_send - time_sound).as_millis() as u64,
636+
recv: (time_stop - time_send).as_millis() as u64,
637+
size,
638+
};
566639

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

0 commit comments

Comments
 (0)