From 205e0ad302d6130e171cdcf4fef40dd71913d97c Mon Sep 17 00:00:00 2001 From: Developer01 Date: Mon, 12 Oct 2026 15:51:22 +0200 Subject: [PATCH] =?UTF-8?q?=C3=9Cberwachung=20k=C3=BCrzlich=20aktiver=20Be?= =?UTF-8?q?nutzer=20hinzugef=C3=BCgt=20Die=20Klasse=20`EDMIService`=20wurd?= =?UTF-8?q?e=20erweitert,=20um=20k=C3=BCrzlich=20aktive=20Benutzer=20zu=20?= =?UTF-8?q?=C3=BCberwachen.=20Eine=20neue=20`ConcurrentDictionary`=20namen?= =?UTF-8?q?s=20`=5FRecentUsers`=20speichert=20die=20letzten=20Aktivit?= =?UTF-8?q?=C3=A4ten=20von=20Benutzern,=20die=20maximal=2015=20Minuten=20z?= =?UTF-8?q?ur=C3=BCckliegen.=20Die=20Methode=20`GetServiceStatus`=20wurde?= =?UTF-8?q?=20angepasst,=20um=20diese=20Informationen=20bereitzustellen=20?= =?UTF-8?q?und=20=C3=A4ltere=20Eintr=C3=A4ge=20zu=20bereinigen.=20Die=20Kl?= =?UTF-8?q?asse=20`ServiceStatusResponse`=20enth=C3=A4lt=20nun=20eine=20ne?= =?UTF-8?q?ue=20Eigenschaft=20`RecentUsers`,=20die=20die=20k=C3=BCrzlich?= =?UTF-8?q?=20aktiven=20Benutzer=20zur=C3=BCckgibt.=20Die=20Datei=20`GetSe?= =?UTF-8?q?rviceStatus.vb`=20wurde=20entfernt=20und=20durch=20eine=20neue?= =?UTF-8?q?=20Struktur=20im=20Namespace=20`Messages`=20ersetzt.=20Die=20Pr?= =?UTF-8?q?ojektdatei=20`EDMIService.vbproj`=20wurde=20entsprechend=20aktu?= =?UTF-8?q?alisiert.=20Zus=C3=A4tzlich=20wurden=20die=20Datenkontrakte=20i?= =?UTF-8?q?n=20`ServiceStatusResponse`=20optimiert,=20indem=20die=20Eigens?= =?UTF-8?q?chaften=20mit=20einer=20expliziten=20Reihenfolge=20(`Order`)=20?= =?UTF-8?q?versehen=20wurden.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Service.EDMIService/EDMIService.vb | 33 +++++++++++++++---- Service.EDMIService/EDMIService.vbproj | 1 - Service.EDMIService/GetServiceStatus.vb | 6 ---- .../Messages/GetServiceStatus.vb | 11 ++++--- 4 files changed, 32 insertions(+), 19 deletions(-) delete mode 100644 Service.EDMIService/GetServiceStatus.vb diff --git a/Service.EDMIService/EDMIService.vb b/Service.EDMIService/EDMIService.vb index 54512f66..2c36be07 100644 --- a/Service.EDMIService/EDMIService.vb +++ b/Service.EDMIService/EDMIService.vb @@ -31,6 +31,9 @@ Public Class EDMIService Public Const TBIDB_ACCESSRIGHT = "TBIDB_ACCESSRIGHT" ' ── Aktive Sessions: SessionId → Username (thread-safe) ────────────────── Private Shared ReadOnly _ActiveSessions As New Collections.Concurrent.ConcurrentDictionary(Of String, String) + ' ► NEU: Letzte Aktivität je Benutzer (für Monitoring auch nach Session-Close) + Private Shared ReadOnly _RecentUsers As New Collections.Concurrent.ConcurrentDictionary(Of String, DateTime) + Private Shared ReadOnly _RecentUserMaxAge As TimeSpan = TimeSpan.FromMinutes(15) Public Shared ReadOnly Property ActiveSessions As Integer Get @@ -121,6 +124,8 @@ Public Class EDMIService End If _ActiveSessions(oSessionId) = _Username + ' ► NEU: Letzten Zugriff für diesen Benutzer aktualisieren + _RecentUsers(_Username) = DateTime.Now ' ← Neu: Session-Start loggen _Logger.Debug("Session opened | User=[{0}] | SessionId=[{1}] | ActiveSessions=[{2}]", _Username, oSessionId, _ActiveSessions.Count) @@ -160,15 +165,29 @@ Public Class EDMIService ''' Returns a snapshot of all currently active sessions for monitoring purposes ''' Public Function GetServiceStatus() As Messages.ServiceStatusResponse Implements IEDMIService.GetServiceStatus - _Logger.Debug("GetServiceStatus called by User=[{0}]", _Username) - ' Snapshot nur einmal erstellen, nicht zweimal iterieren: + ' Aktuell offene Sessions Dim oSnapshot = _ActiveSessions.ToArray() + + ' ► NEU: Kürzlich aktive Benutzer (max. 15 Min. alt) bereinigen und zurückgeben + Dim oCutoff = DateTime.Now.Subtract(_RecentUserMaxAge) + Dim oStaleKeys = _RecentUsers.Where(Function(p) p.Value < oCutoff).Select(Function(p) p.Key).ToList() + For Each oKey In oStaleKeys + Dim oIgnored As DateTime + _RecentUsers.TryRemove(oKey, oIgnored) + Next + + Dim oRecentUserList = _RecentUsers. + OrderByDescending(Function(p) p.Value). + Select(Function(p) $"{p.Key} (zuletzt: {p.Value:HH:mm:ss})"). + ToList() + Return New Messages.ServiceStatusResponse With { - .ActiveSessionCount = oSnapshot.Length, - .ActiveUsers = oSnapshot.Select(Function(p) p.Value).Distinct().OrderBy(Function(u) u).ToList(), - .ActiveSessions = oSnapshot.ToDictionary(Function(p) p.Key, Function(p) p.Value), - .Timestamp = DateTime.Now - } + .ActiveSessionCount = oSnapshot.Length, + .ActiveUsers = oSnapshot.Select(Function(p) p.Value).Distinct().OrderBy(Function(u) u).ToList(), + .ActiveSessions = oSnapshot.ToDictionary(Function(p) p.Key, Function(p) p.Value), + .Timestamp = DateTime.Now, + .RecentUsers = oRecentUserList ' ◄ NEU – im Response-Objekt ergänzen + } End Function #End Region diff --git a/Service.EDMIService/EDMIService.vbproj b/Service.EDMIService/EDMIService.vbproj index 77b88c2a..e956fe74 100644 --- a/Service.EDMIService/EDMIService.vbproj +++ b/Service.EDMIService/EDMIService.vbproj @@ -155,7 +155,6 @@ - diff --git a/Service.EDMIService/GetServiceStatus.vb b/Service.EDMIService/GetServiceStatus.vb deleted file mode 100644 index df7fd77c..00000000 --- a/Service.EDMIService/GetServiceStatus.vb +++ /dev/null @@ -1,6 +0,0 @@ -Imports System.Runtime.Serialization - -Public Class GetServiceStatus - - -End Class diff --git a/Service.EDMIService/Messages/GetServiceStatus.vb b/Service.EDMIService/Messages/GetServiceStatus.vb index 34c75466..01bed182 100644 --- a/Service.EDMIService/Messages/GetServiceStatus.vb +++ b/Service.EDMIService/Messages/GetServiceStatus.vb @@ -1,11 +1,12 @@ Imports System.Runtime.Serialization Namespace Messages - + Public Class ServiceStatusResponse - Public Property ActiveSessionCount As Integer - Public Property ActiveUsers As List(Of String) ' Distinct, sortiert - Public Property ActiveSessions As Dictionary(Of String, String) ' SessionId → Username - Public Property Timestamp As DateTime + Public Property ActiveSessionCount As Integer + Public Property ActiveUsers As List(Of String) + Public Property ActiveSessions As Dictionary(Of String, String) + Public Property Timestamp As DateTime + Public Property RecentUsers As List(Of String) = New List(Of String)() End Class End Namespace \ No newline at end of file