Files
scadalink-design/deprecated/lmxproxy/src-reference/ZB.MOM.WW.LmxProxy.Host/Services/SessionManager.cs
Joseph Doherty 9dccf8e72f deprecate(lmxproxy): move all LmxProxy code, tests, and docs to deprecated/
LmxProxy is no longer needed. Moved the entire lmxproxy/ workspace, DCL
adapter files, and related docs to deprecated/. Removed LmxProxy registration
from DataConnectionFactory, project reference from DCL, protocol option from
UI, and cleaned up all requirement docs.
2026-04-08 15:56:23 -04:00

183 lines
5.7 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Serilog;
namespace ZB.MOM.WW.LmxProxy.Host.Services
{
/// <summary>
/// Manages client sessions for the gRPC service.
/// Tracks active sessions with unique session IDs.
/// </summary>
public class SessionManager : IDisposable
{
private static readonly ILogger Logger = Log.ForContext<SessionManager>();
private readonly ConcurrentDictionary<string, SessionInfo> _sessions = new();
private bool _disposed;
/// <summary>
/// Gets the number of active sessions.
/// </summary>
public int ActiveSessionCount => _sessions.Count;
/// <summary>
/// Creates a new session for a client.
/// </summary>
/// <param name="clientId">The client identifier.</param>
/// <param name="apiKey">The API key used for authentication (optional).</param>
/// <returns>The session ID for the new session.</returns>
/// <exception cref="ObjectDisposedException">Thrown if the manager is disposed.</exception>
public string CreateSession(string clientId, string apiKey = null)
{
if (_disposed)
{
throw new ObjectDisposedException(nameof(SessionManager));
}
var sessionId = Guid.NewGuid().ToString("N");
var sessionInfo = new SessionInfo
{
SessionId = sessionId,
ClientId = clientId ?? string.Empty,
ApiKey = apiKey ?? string.Empty,
ConnectedAt = DateTime.UtcNow,
LastActivity = DateTime.UtcNow
};
_sessions[sessionId] = sessionInfo;
Logger.Information("Created session {SessionId} for client {ClientId}", sessionId, clientId);
return sessionId;
}
/// <summary>
/// Validates a session ID and updates the last activity timestamp.
/// </summary>
/// <param name="sessionId">The session ID to validate.</param>
/// <returns>True if the session is valid; otherwise, false.</returns>
public bool ValidateSession(string sessionId)
{
if (_disposed)
{
return false;
}
if (string.IsNullOrEmpty(sessionId))
{
return false;
}
if (_sessions.TryGetValue(sessionId, out SessionInfo sessionInfo))
{
sessionInfo.LastActivity = DateTime.UtcNow;
return true;
}
return false;
}
/// <summary>
/// Gets the session information for a session ID.
/// </summary>
/// <param name="sessionId">The session ID.</param>
/// <returns>The session information, or null if not found.</returns>
public SessionInfo GetSession(string sessionId)
{
if (_disposed || string.IsNullOrEmpty(sessionId))
{
return null;
}
_sessions.TryGetValue(sessionId, out SessionInfo sessionInfo);
return sessionInfo;
}
/// <summary>
/// Terminates a session.
/// </summary>
/// <param name="sessionId">The session ID to terminate.</param>
/// <returns>True if the session was terminated; otherwise, false.</returns>
public bool TerminateSession(string sessionId)
{
if (_disposed || string.IsNullOrEmpty(sessionId))
{
return false;
}
if (_sessions.TryRemove(sessionId, out SessionInfo sessionInfo))
{
Logger.Information("Terminated session {SessionId} for client {ClientId}", sessionId, sessionInfo.ClientId);
return true;
}
return false;
}
/// <summary>
/// Gets all active sessions.
/// </summary>
/// <returns>A list of all active session information.</returns>
public IReadOnlyList<SessionInfo> GetAllSessions()
{
return _sessions.Values.ToList();
}
/// <summary>
/// Disposes the session manager and clears all sessions.
/// </summary>
public void Dispose()
{
if (_disposed)
{
return;
}
_disposed = true;
var count = _sessions.Count;
_sessions.Clear();
Logger.Information("SessionManager disposed, cleared {Count} sessions", count);
}
}
/// <summary>
/// Contains information about a client session.
/// </summary>
public class SessionInfo
{
/// <summary>
/// Gets or sets the unique session identifier.
/// </summary>
public string SessionId { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the client identifier.
/// </summary>
public string ClientId { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the API key used for this session.
/// </summary>
public string ApiKey { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the time when the session was created.
/// </summary>
public DateTime ConnectedAt { get; set; }
/// <summary>
/// Gets or sets the time of the last activity on this session.
/// </summary>
public DateTime LastActivity { get; set; }
/// <summary>
/// Gets the connected time as UTC ticks for the gRPC response.
/// </summary>
public long ConnectedSinceUtcTicks => ConnectedAt.Ticks;
}
}