This commit is contained in:
GlassOnTin 2025-06-05 23:20:32 +02:00 committed by GitHub
commit ad2e628cf3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 107 additions and 10 deletions

View File

@ -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

View File

@ -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();

View File

@ -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;
}
}