From a528e9f3b2d92c3a478dc3a2bd54ac2acadd92aa Mon Sep 17 00:00:00 2001 From: Tim Eertmoed Date: Sun, 13 Sep 2026 14:14:38 +0200 Subject: [PATCH] Version 2.8.21: die Seite wartet nicht mehr stumm --- apps/tesm/pyproject.toml | 2 +- packages/tesm-core/pyproject.toml | 2 +- .../tesm_core/static/tesm_core/js/screen.js | 33 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/apps/tesm/pyproject.toml b/apps/tesm/pyproject.toml index 0580e19..7f8aebf 100644 --- a/apps/tesm/pyproject.toml +++ b/apps/tesm/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm" -version = "2.8.20" +version = "2.8.21" description = "TESM -- Verwaltung und Ueberwachung von PoE-Endgeraeten und Aruba-Switchen" requires-python = ">=3.11" dependencies = [ diff --git a/packages/tesm-core/pyproject.toml b/packages/tesm-core/pyproject.toml index 65affe2..467cd09 100644 --- a/packages/tesm-core/pyproject.toml +++ b/packages/tesm-core/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm-core" -version = "2.8.10" +version = "2.8.11" description = "Gemeinsames Anwendungsgeruest (Auth, RBAC, Navigation, Design-System, Migrationen) fuer TESM und TESM-Lizenzserver" requires-python = ">=3.11" dependencies = [ diff --git a/packages/tesm-core/src/tesm_core/static/tesm_core/js/screen.js b/packages/tesm-core/src/tesm_core/static/tesm_core/js/screen.js index f42519e..50c50ff 100644 --- a/packages/tesm-core/src/tesm_core/static/tesm_core/js/screen.js +++ b/packages/tesm-core/src/tesm_core/static/tesm_core/js/screen.js @@ -38,6 +38,15 @@ const gescheitert = new Set(); //: RealVNC Server zaehlt abgebrochene Versuche mit -- wer dreimal anklopft, //: sperrt sich aus. const HOECHSTENS = 2; + +//: So lange darf "wird aufgebaut" stehen, bevor die Seite selbst nachsieht. +//: +//: Der Server hat eigene Grenzen und meldet sich, wenn das Geraet schweigt -- +//: aber nur, wenn die Leitung dorthin ueberhaupt steht. Kommt die +//: WebSocket-Verbindung gar nicht erst zustande, wartet noVNC ohne jedes +//: Ereignis, und die Seite stuende stumm bis zum Seitenwechsel. Genau so +//: gemeldet: "Verbindung wird aufgebaut ..." und sonst nichts. +const AUFBAU_GRENZE = 12000; // Den *Grund* eines Fehlschlags kennt nur ``_fail`` -- das Ereignis // "disconnect" traegt ihn nicht, und der Weg ueber die Protokollausgabe // funktioniert nicht: die Bibliothek bindet ``console.error`` beim Laden, also @@ -87,6 +96,7 @@ function starten(wurzel) { ); let rfb = null; + let aufbauUhr = 0; let versuche = 0; let stand = false; let letzterZugang = {}; @@ -164,6 +174,25 @@ function starten(wurzel) { letzterCode = 0; letzterZugang = zugang; versuche += 1; + window.clearTimeout(aufbauUhr); + aufbauUhr = window.setTimeout(() => { + // Weder verbunden noch abgebrochen noch nach Zugangsdaten gefragt -- + // dann haengt es an der Leitung, nicht am VNC-Server. + melden("Es kommt keine Antwort. Wird geprüft, woran es liegt …", "warnung"); + streckeTesten().then((steht) => { + melden( + steht + ? "Die WebSocket-Strecke zu TESM steht, aber die Sitzung kommt nicht " + + "zustande. Antwortet der VNC-Server auf dem Gerät noch? Ein Neustart " + + "des VNC-Dienstes räumt eine Sperre ab." + : "Die WebSocket-Verbindung zu TESM kommt nicht zustande – auch eine " + + "einfache Probe scheitert. Ein Proxy zwischen Browser und TESM muss " + + "die Kopfzeilen Upgrade und Connection durchreichen (nginx: " + + "location /ws/ mit proxy_set_header Upgrade $http_upgrade).", + "fehler", + ); + }); + }, AUFBAU_GRENZE); // Was abgerissen ist, wird nicht noch einmal gewaehlt. Sonst faende noVNC // dasselbe Verfahren wieder zuerst -- und der zweite Anlauf waere eine @@ -185,6 +214,7 @@ function starten(wurzel) { rfb.focusOnClick = true; rfb.addEventListener("connect", () => { + window.clearTimeout(aufbauUhr); stand = true; melden(`Verbunden mit ${wurzel.dataset.ziel}`, "ok"); abfrage.hidden = true; @@ -194,6 +224,7 @@ function starten(wurzel) { }); rfb.addEventListener("disconnect", (ereignis) => { + window.clearTimeout(aufbauUhr); leinwand.hidden = true; knopfTrennen.hidden = true; knopfStrg.hidden = true; @@ -236,6 +267,7 @@ function starten(wurzel) { }); rfb.addEventListener("credentialsrequired", (ereignis) => { + window.clearTimeout(aufbauUhr); const gefragt = ereignis.detail.types || ["password"]; abfrage.hidden = false; feldBenutzer.closest("label").hidden = !gefragt.includes("username"); @@ -244,6 +276,7 @@ function starten(wurzel) { }); rfb.addEventListener("securityfailure", (ereignis) => { + window.clearTimeout(aufbauUhr); melden( `Anmeldung abgelehnt: ${ereignis.detail.reason || "kein Grund genannt"}`, "fehler",