mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-06-07 09:52:49 +08:00
Merge 64cfdf67a7
into e79724644d
This commit is contained in:
commit
ad2e628cf3
13
src/ipc.rs
13
src/ipc.rs
@ -420,10 +420,10 @@ async fn handle(data: Data, stream: &mut Connection) {
|
||||
if is_server() {
|
||||
let _ = privacy_mode::turn_off_privacy(0, Some(PrivacyModeState::OffByPeer));
|
||||
}
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
if crate::is_main() {
|
||||
// below part is for main windows can be reopen during rustdesk installation and installing service from UI
|
||||
// this make new ipc server (domain socket) can be created.
|
||||
#[cfg(not(windows))]
|
||||
std::fs::remove_file(&Config::ipc_path("")).ok();
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
@ -442,6 +442,17 @@ async fn handle(data: Data, stream: &mut Connection) {
|
||||
.spawn()
|
||||
.ok();
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
// On Windows, when service is being installed, wait a bit then restart the GUI
|
||||
hbb_common::sleep(2.0).await;
|
||||
if let Ok(exe) = std::env::current_exe() {
|
||||
std::process::Command::new(&exe)
|
||||
.arg("--no-server")
|
||||
.spawn()
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
// leave above open a little time
|
||||
hbb_common::sleep(0.3).await;
|
||||
// in case below exit failed
|
||||
|
@ -547,13 +547,40 @@ pub async fn start_server(is_server: bool, no_server: bool) {
|
||||
if is_server {
|
||||
crate::common::set_server_running(true);
|
||||
std::thread::spawn(move || {
|
||||
if let Err(err) = crate::ipc::start("") {
|
||||
log::error!("Failed to start ipc: {}", err);
|
||||
if crate::is_server() {
|
||||
log::error!("ipc is occupied by another process, try kill it");
|
||||
std::thread::spawn(stop_main_window_process).join().ok();
|
||||
// Retry IPC server start with exponential backoff during service installation
|
||||
let mut attempts = 0;
|
||||
let max_attempts = 10; // Increase attempts to handle service installation scenario
|
||||
let mut wait_time = 1;
|
||||
|
||||
loop {
|
||||
match crate::ipc::start("") {
|
||||
Ok(_) => break,
|
||||
Err(err) => {
|
||||
attempts += 1;
|
||||
log::error!("Failed to start ipc (attempt {}/{}): {}", attempts, max_attempts, err);
|
||||
|
||||
if attempts >= max_attempts {
|
||||
if crate::is_server() {
|
||||
log::error!("ipc is occupied by another process after {} attempts", max_attempts);
|
||||
// Check if we're being started as part of service installation
|
||||
// In that case, the GUI needs time to close its IPC server
|
||||
let is_service_installation = std::env::var("RUSTDESK_SERVICE_INSTALLATION").is_ok();
|
||||
|
||||
if !is_service_installation {
|
||||
log::error!("Not during service installation, try kill the process occupying IPC");
|
||||
std::thread::spawn(stop_main_window_process).join().ok();
|
||||
} else {
|
||||
log::info!("Service installation detected, GUI should restart itself");
|
||||
}
|
||||
}
|
||||
std::process::exit(-1);
|
||||
}
|
||||
|
||||
// Wait before retrying with exponential backoff
|
||||
std::thread::sleep(std::time::Duration::from_secs(wait_time));
|
||||
wait_time = std::cmp::min(wait_time * 2, 10); // Cap at 10 seconds
|
||||
}
|
||||
}
|
||||
std::process::exit(-1);
|
||||
}
|
||||
});
|
||||
input_service::fix_key_down_timeout_loop();
|
||||
|
@ -1157,9 +1157,14 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
|
||||
#[cfg(target_os = "windows")]
|
||||
let mut enable_file_transfer = "".to_owned();
|
||||
let is_cm = crate::common::is_cm();
|
||||
let mut connection_attempts = 0;
|
||||
let max_attempts = 10; // Give service time to start
|
||||
|
||||
loop {
|
||||
if let Ok(mut c) = ipc::connect(1000, "").await {
|
||||
// Increase timeout and retry attempts when service might be starting
|
||||
let timeout = if connection_attempts < 3 { 1000 } else { 2000 };
|
||||
if let Ok(mut c) = ipc::connect(timeout, "").await {
|
||||
connection_attempts = 0; // Reset on successful connection
|
||||
let mut timer = crate::rustdesk_interval(time::interval(time::Duration::from_secs(1)));
|
||||
loop {
|
||||
tokio::select! {
|
||||
@ -1167,8 +1172,30 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
|
||||
match res {
|
||||
Err(err) => {
|
||||
log::error!("ipc connection closed: {}", err);
|
||||
// Don't quit immediately if we're starting the service
|
||||
// Give the service time to start and allow retries
|
||||
if is_cm {
|
||||
crate::ui_cm_interface::quit_cm();
|
||||
// Check if service is starting up
|
||||
let mut service_starting = false;
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
// On Windows, check if we're in elevated mode or if service is being installed
|
||||
let is_elevated = crate::platform::is_elevated(None).unwrap_or(false);
|
||||
service_starting = !is_elevated && (crate::platform::installing_service() ||
|
||||
(crate::platform::is_installed() && !crate::platform::is_root()));
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
// On other platforms, check if service is installed but not running as root
|
||||
service_starting = crate::platform::is_installed() &&
|
||||
!crate::platform::is_root();
|
||||
}
|
||||
|
||||
if !service_starting {
|
||||
crate::ui_cm_interface::quit_cm();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1247,6 +1274,36 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
|
||||
.unwrap()
|
||||
.insert("ipc-closed".to_owned(), "Y".to_owned());
|
||||
break;
|
||||
} else {
|
||||
// Connection failed
|
||||
connection_attempts += 1;
|
||||
log::warn!("IPC connection attempt {} failed", connection_attempts);
|
||||
|
||||
// Only quit if we've exceeded max attempts and not during service startup
|
||||
if is_cm && connection_attempts >= max_attempts {
|
||||
let mut service_starting = false;
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
// On Windows, check if service is being installed/started
|
||||
let is_elevated = crate::platform::is_elevated(None).unwrap_or(false);
|
||||
service_starting = !is_elevated && (crate::platform::installing_service() ||
|
||||
(crate::platform::is_installed() && !crate::platform::is_root()));
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
// On other platforms
|
||||
service_starting = crate::platform::is_installed() &&
|
||||
!crate::platform::is_root();
|
||||
}
|
||||
|
||||
if !service_starting {
|
||||
log::error!("Failed to connect after {} attempts, quitting", max_attempts);
|
||||
crate::ui_cm_interface::quit_cm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*UI_STATUS.lock().unwrap() = UiStatus {
|
||||
status_num: -1,
|
||||
@ -1259,7 +1316,9 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
|
||||
#[cfg(feature = "flutter")]
|
||||
video_conn_count,
|
||||
};
|
||||
sleep(1.).await;
|
||||
// Use exponential backoff for retries during service startup
|
||||
let sleep_time = if connection_attempts < 5 { 1. } else { 2. };
|
||||
sleep(sleep_time).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user