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.
183 lines
5.7 KiB
C#
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;
|
|
}
|
|
}
|