From dddeb26946417883d1e6a900bce6200e5479149e Mon Sep 17 00:00:00 2001 From: Ruslan Date: Mon, 4 May 2026 07:15:31 +0000 Subject: [PATCH] fix: persist should_be_connected state to disk, restore on manager restart --- rdp-proxy/manager.py | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/rdp-proxy/manager.py b/rdp-proxy/manager.py index cc0daed..0c54149 100644 --- a/rdp-proxy/manager.py +++ b/rdp-proxy/manager.py @@ -19,9 +19,27 @@ RDP_PASSWORD = os.environ.get("RDP_PASSWORD", "") RDP_DOMAIN = os.environ.get("RDP_DOMAIN", "") RDP_SECURITY = os.environ.get("RDP_SECURITY", "") +STATE_FILE = "/tmp/rdp_state.json" + _lock = threading.Lock() _proc: subprocess.Popen | None = None -_should_be_connected = False # set True on /connect, False on /disconnect +_should_be_connected = False + + +def _save_state(): + try: + with open(STATE_FILE, "w") as f: + json.dump({"should_be_connected": _should_be_connected}, f) + except Exception: + pass + + +def _load_state() -> bool: + try: + with open(STATE_FILE) as f: + return json.load(f).get("should_be_connected", False) + except Exception: + return False def _build_args(): @@ -57,7 +75,6 @@ def _launch(): def _monitor_loop(): - """Auto-reconnect if xfreerdp crashes while session should be active.""" while True: time.sleep(5) with _lock: @@ -69,9 +86,7 @@ def _monitor_loop(): _launch() -threading.Thread(target=_monitor_loop, daemon=True).start() def _anti_idle_loop(): - """Move mouse inside xfreerdp window every 30s — works on any remote OS.""" env = {**os.environ, "DISPLAY": DISPLAY} toggle = False while True: @@ -87,29 +102,27 @@ def _anti_idle_loop(): ) win_id = r.stdout.decode().strip().splitlines()[0] if r.stdout.strip() else "" if win_id: - # Чередуем позицию — tiny mouse jiggle внутри окна xfreerdp x, y = (960, 540) if toggle else (970, 550) subprocess.run( ["xdotool", "mousemove", "--window", win_id, str(x), str(y)], env=env, capture_output=True, timeout=5, ) - toggle = not toggle subprocess.run( ["xdotool", "key", "--window", win_id, "--clearmodifiers", "shift"], env=env, capture_output=True, timeout=5, ) - log.debug("anti_idle mousemove window=%s pos=%s,%s", win_id, x, y) + toggle = not toggle + log.debug("anti_idle jiggle window=%s pos=%s,%s", win_id, x, y) else: log.debug("anti_idle: xfreerdp window not found") except Exception as e: log.debug("anti_idle error: %s", e) +threading.Thread(target=_monitor_loop, daemon=True).start() threading.Thread(target=_anti_idle_loop, daemon=True).start() - - class Handler(BaseHTTPRequestHandler): def log_message(self, fmt, *args): pass @@ -141,6 +154,7 @@ class Handler(BaseHTTPRequestHandler): if self.path == "/connect": with _lock: _should_be_connected = True + _save_state() if _proc is not None and _proc.poll() is None: self._json(200, {"ok": True, "pid": _proc.pid, "already": True}) return @@ -149,6 +163,7 @@ class Handler(BaseHTTPRequestHandler): elif self.path == "/disconnect": with _lock: _should_be_connected = False + _save_state() if _proc is not None: _proc.terminate() try: @@ -165,5 +180,9 @@ class Handler(BaseHTTPRequestHandler): if __name__ == "__main__": if not RDP_HOST: log.warning("RDP_HOST not set — connect calls will fail") + if _load_state(): + log.info("restoring state: reconnecting xfreerdp") + _should_be_connected = True + _launch() log.info("manager started on :7001") HTTPServer(("0.0.0.0", 7001), Handler).serve_forever()