Projektbereinigung: Entfernung alter Module und Ressourcen

Mehrere Module (`ChatAddUser`, `ChatControl`, `ChatNewConv`) und
deren zugehörige Dateien wurden vollständig aus dem Projekt
entfernt. Dies umfasst Designer-, Ressourcen- und Projektdateien
sowie Backup-Dateien.

Zusätzlich wurden nicht mehr benötigte Bilder, Lizenzdateien
(`licenses.licx`), Konfigurationsdateien (`app.config`,
`packages.config`) und generierte Dateien entfernt.

Die Abhängigkeiten in `App.config` wurden aktualisiert, und neue
Bibliotheken wie `System.Threading.Tasks.Extensions` wurden
hinzugefügt. Eine Methode in `Annotations.vb` wurde angepasst,
um Änderungen in der zugrunde liegenden API zu berücksichtigen.

Diese Änderungen sind Teil einer umfassenden Bereinigung und
Modernisierung des Projekts.
This commit is contained in:
Developer01
2026-09-25 13:58:48 +02:00
parent 1a9ddc6cf7
commit 3ad08929ff
132 changed files with 5540 additions and 5553 deletions

View File

@@ -27,38 +27,102 @@ Public Class EDMIService
Public Const TBIDB_DOC_INFO = "TBIDB_DOC_INFO"
Public Const TBIDB_ACCESSRIGHT = "TBIDB_ACCESSRIGHT"
' ── Aktive Sessions: SessionId → Username (thread-safe) ──────────────────
Private Shared ReadOnly _ActiveSessions As New Collections.Concurrent.ConcurrentDictionary(Of String, String)
Public Shared ReadOnly Property ActiveSessions As Integer
Get
Return _ActiveSessions.Count
End Get
End Property
Public Shared ReadOnly Property ActiveSessionUsers As IReadOnlyCollection(Of String)
Get
Return _ActiveSessions.Values.Distinct().OrderBy(Function(u) u).ToList().AsReadOnly()
End Get
End Property
' ─────────────────────────────────────────────────────────────────────────
Private ReadOnly _Logger As Logger
Private ReadOnly _Debug As Boolean = False
Private ReadOnly _Username As String
Private ReadOnly _IDBHelpers As IDB.Helpers
' ── Konfigurationswerte für späteres Logging in New() ────────────────────
Private Shared _ConfiguredEndpoint As String = String.Empty
Private Shared _ConfiguredMaxCalls As Integer = 0
Private Shared _ConfiguredMaxSessions As Integer = 0
' ─────────────────────────────────────────────────────────────────────────
Public Shared Sub Configure(Config As ServiceConfiguration)
Dim oBaseAddress = Config.BaseAddresses.Item(0)
Dim oBinding = API.Channel.GetBinding()
Dim oAddress = New EndpointAddress(oBaseAddress)
' See: https://stackoverflow.com/questions/42327988/addserviceendpoint-throws-key-is-null
Dim oDescription = ContractDescription.GetContract(GetType(IEDMIService), GetType(EDMIService))
Dim oEndpoint As New ServiceEndpoint(oDescription, oBinding, oAddress)
Config.AddServiceEndpoint(oEndpoint)
Config.Description.Behaviors.Add(New ServiceDebugBehavior With {.IncludeExceptionDetailInFaults = True})
Dim oThrottling = Config.Description.Behaviors.Find(Of ServiceThrottlingBehavior)()
If oThrottling Is Nothing Then
oThrottling = New ServiceThrottlingBehavior()
Config.Description.Behaviors.Add(oThrottling)
End If
Dim oCpuCores As Integer = Environment.ProcessorCount
oThrottling.MaxConcurrentCalls = Math.Max(200, 32 * oCpuCores) ' war 16×
oThrottling.MaxConcurrentSessions = Math.Max(400, 150 * oCpuCores) ' war 100×
oThrottling.MaxConcurrentInstances = Integer.MaxValue
' ── Werte für späteres Logging speichern ─────────────────────────────
_ConfiguredEndpoint = oBaseAddress.ToString()
_ConfiguredMaxCalls = oThrottling.MaxConcurrentCalls
_ConfiguredMaxSessions = oThrottling.MaxConcurrentSessions
' ─────────────────────────────────────────────────────────────────────
End Sub
Public Sub New()
Dim oOperationContext As OperationContext = OperationContext.Current
Dim oInstanceContext As InstanceContext = oOperationContext.InstanceContext
Dim oUsername = StripDomainFromUsername(oOperationContext.ServiceSecurityContext.WindowsIdentity.Name)
Dim oSessionId As String = If(oOperationContext.SessionId, $"no-session_{Guid.NewGuid().ToString("N").Substring(0, 8)}")
_Username = oUsername
_Username = If(String.IsNullOrWhiteSpace(oUsername), "unknown", oUsername)
_Logger = LogConfig.GetLogger()
_Logger.Debug("New Request by User [{0}]", _Username)
_IDBHelpers = New IDB.Helpers(LogConfig, MSSQL_IDB)
End Sub
' ── Konfiguration beim ersten Aufruf loggen ───────────────────────────
If Not String.IsNullOrEmpty(_ConfiguredEndpoint) Then
_Logger.Info("✔ EDMIService configured | Endpoint=[{0}] | MaxCalls=[{1}] | MaxSessions=[{2}] | CPUs=[{3}]",
_ConfiguredEndpoint, _ConfiguredMaxCalls, _ConfiguredMaxSessions, Environment.ProcessorCount)
_ConfiguredEndpoint = String.Empty
End If
' ─────────────────────────────────────────────────────────────────────
' ── Session registrieren ──────────────────────────────────────────────
_ActiveSessions(oSessionId) = _Username
BuildUserList()
AddHandler oInstanceContext.Closed, Sub()
Dim oRemoved As String = Nothing
_ActiveSessions.TryRemove(oSessionId, oRemoved)
BuildUserList()
End Sub
AddHandler oInstanceContext.Faulted, Sub()
Dim oRemoved As String = Nothing
_ActiveSessions.TryRemove(oSessionId, oRemoved)
_Logger.Warn("⚠ Session faulted | User=[{0}] | ActiveSessions=[{1}]",
_Username, _ActiveSessions.Count)
End Sub
End Sub
''' <summary>
''' Erstellt die User-Liste nur wenn nötig (Debug-Guard vorher prüfen).
''' </summary>
Private Shared Function BuildUserList() As String
Return String.Join(", ", _ActiveSessions.Values.Distinct().OrderBy(Function(u) u))
End Function
#Region "=== Base ==="
Public Function Heartbeat() As Boolean Implements IEDMIService.Heartbeat
Return True
@@ -69,6 +133,20 @@ Public Class EDMIService
Dim oGetClientConfig As New Base.GetClientConfig.GetClientConfigMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
Return oGetClientConfig.Run()
End Function
''' <summary>
''' Returns a snapshot of all currently active sessions for monitoring purposes
''' </summary>
Public Function GetServiceStatus() As Messages.ServiceStatusResponse Implements IEDMIService.GetServiceStatus
_Logger.Debug("GetServiceStatus called by User=[{0}]", _Username)
' Snapshot nur einmal erstellen, nicht zweimal iterieren:
Dim oSnapshot = _ActiveSessions.ToArray()
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
}
End Function
#End Region
Public Function NewFile(Data As NewFile.NewFileRequest) As NewFile.NewFileResponse Implements IEDMIService.NewFile
@@ -121,9 +199,16 @@ Public Class EDMIService
#Region "=== Database ==="
Private Shared _CachedTablesSnapshot As List(Of String) = Nothing
Private Shared _CachedTablesExpiry As DateTime = DateTime.MinValue
Public Function GetCachedTables() As List(Of String) Implements IEDMIService.GetCachedTables
Try
Return GlobalState.GetCachedTables()
If _CachedTablesSnapshot Is Nothing OrElse DateTime.Now > _CachedTablesExpiry Then
_CachedTablesSnapshot = GlobalState.GetCachedTables()
_CachedTablesExpiry = DateTime.Now.AddSeconds(30)
End If
Return _CachedTablesSnapshot
Catch ex As Exception
_Logger.Error(ex)
Return New List(Of String)
@@ -167,7 +252,7 @@ Public Class EDMIService
#Region "=== Database (MSSQL IDB) ==="
Public Function ReturnDatatable_MSSQL_IDB(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_MSSQL_IDB
Try
_Logger.Info($"ReturnDatatable_MSSQL_IDB, SQL: {SQL}")
_Logger.Debug($"ReturnDatatable_MSSQL_IDB, SQL: {SQL}")
Dim oResult As DataTable = MSSQL_IDB.GetDatatable(SQL)
oResult.TableName = "DD_RESULT"
Return New TableResult(oResult)
@@ -585,7 +670,7 @@ Public Class EDMIService
Dim oRow As DataRow = oRows.First()
Dim oRightAsInt = oRow.Item("ACCESSRIGHT")
Select Case oRight
Select Case oRightAsInt
Case 1
oRight = AccessRight.VIEW_ONLY
Case 2

View File

@@ -155,6 +155,8 @@
<Compile Include="BaseMethod.vb" />
<Compile Include="ClassConstants.vb" />
<Compile Include="Config.vb" />
<Compile Include="GetServiceStatus.vb" />
<Compile Include="Messages\GetServiceStatus.vb" />
<Compile Include="Methods\Base\GetClientConfig\GetClientConfigMethod.vb" />
<Compile Include="Methods\Base\GetClientConfig\GetClientConfigResponse.vb" />
<Compile Include="Methods\Database\DatabaseName.vb" />

View File

@@ -0,0 +1,6 @@
Imports System.Runtime.Serialization
Public Class GetServiceStatus
End Class

View File

@@ -16,6 +16,8 @@ Interface IEDMIService
<OperationContract>
Function GetClientConfig() As Base.GetClientConfig.GetClientConfigResponse
<OperationContract>
Function GetServiceStatus() As Messages.ServiceStatusResponse
#End Region
#Region "Database"

View File

@@ -0,0 +1,11 @@
Imports System.Runtime.Serialization
Namespace Messages
<DataContract>
Public Class ServiceStatusResponse
<DataMember> Public Property ActiveSessionCount As Integer
<DataMember> Public Property ActiveUsers As List(Of String) ' Distinct, sortiert
<DataMember> Public Property ActiveSessions As Dictionary(Of String, String) ' SessionId → Username
<DataMember> Public Property Timestamp As DateTime
End Class
End Namespace

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("EDMIService")>
<Assembly: AssemblyCopyright("2026")>
<Assembly: AssemblyTrademark("2.5.0")>
<Assembly: AssemblyTrademark("2.6.0")>
<Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2.5.0.0")>
<Assembly: AssemblyFileVersion("2.5.0.0")>
<Assembly: AssemblyVersion("2.6.0.0")>
<Assembly: AssemblyFileVersion("2.6.0.0")>

View File

@@ -137,7 +137,7 @@ Public Class WindowsService
Logger.Error(ex)
GracefullyStop()
End Try
Logger.Info("✔ Service [{0}] started successfully!", SERVICE_DISPLAY_NAME)
Logger.Info("✔ Service [{0}] started and initialized successfully!", SERVICE_DISPLAY_NAME)
Catch ex As Exception
Logger.Warn("⚠ Unexpected Error while starting the service: {0}", ex.Message)
Logger.Error(ex)