SummerBestWebForm2/SessionState/SessionManager.cs

133 lines
3.5 KiB
C#
Raw Normal View History

2025-05-15 06:12:34 -04:00
using System.Net;
namespace SummerBestWebForm2.SessionState;
// INTERFACE
public interface ISessionManager
{
Task<MdlSession> GetSession();
Task UpdateSession(MdlSession session);
}
// CODE
/// <summary>
/// Dictionary containing per-user session objects, keyed
/// by sessionId.
/// </summary>
public class SessionManager : ISessionManager
{
private Dictionary<Guid, MdlSession> _sessions = new Dictionary<Guid, MdlSession>();
private readonly ISessionIdManager _sessionIdManager;
private object syncLock1 = new();
public SessionManager(ISessionIdManager sessionIdManager)
{
_sessionIdManager = sessionIdManager;
}
public async Task<MdlSession> GetSession()
{
string key = await _sessionIdManager.GetSessionIdAsync() ?? "";
string ipAddress = await _sessionIdManager.GetIPAddressAsync() ?? "";
Guid theSessionId;
if (!Guid.TryParse(key, out theSessionId))
theSessionId = Guid.Empty;//Guid.Parse(key);
MdlSession session;
bool needToCreateNew = false;
if (!_sessions.ContainsKey(theSessionId))
{
needToCreateNew = true;
}
else if (_sessions[theSessionId].dtExpires < DateTimeOffset.Now)
needToCreateNew = true;
if (needToCreateNew)
{
session = new MdlSession() { SessionId = key, IPAddress = ipAddress };
_sessions.Add(theSessionId, new MdlSession());
}
else
session = _sessions[theSessionId];
// ensure session isn't checked out by wasm
//while (session.IsCheckedOut)
// await Task.Delay(5);
var endTime = DateTime.UtcNow.AddSeconds(10);
while (session.IsCheckedOut)
{
if (DateTime.UtcNow > endTime)
throw new TimeoutException();
await Task.Delay(5);
}
return session;
}
public async Task UpdateSession(MdlSession session)
{
if (session != null)
{
string key = await _sessionIdManager.GetSessionIdAsync() ?? "";
string ipAddress = await _sessionIdManager.GetIPAddressAsync() ?? "";
Guid theSessionId;
if (!Guid.TryParse(key, out theSessionId))
theSessionId = Guid.Empty;//Guid.Parse(key);
if (_sessions.ContainsKey(theSessionId))
{
//session = new MdlSession() { SessionId = key, IPAddress = ipAddress };
session.SessionId = key;
session.dtExpires = DateTimeOffset.Now.AddHours(36); // Rolling expiration date
_sessions[theSessionId] = session;
_sessions[theSessionId].IsCheckedOut = false;
}
else
{
var sess = new MdlSession() { SessionId = key, IPAddress = ipAddress };
_sessions[theSessionId] = session;
}
// Remove stale sessions
lock (syncLock1)
{
try
{
var lstRemove = new HashSet<Guid>();
foreach (var kvp in _sessions)
{
if (kvp.Value.dtExpires < DateTimeOffset.Now && !lstRemove.Contains(kvp.Key))
lstRemove.Add(kvp.Key);
}
foreach (var rmv in lstRemove)
_sessions.Remove(rmv);
lstRemove.Clear();
}
catch (Exception ex)
{
// do something
}
}
}
} //UpdateSession
/// <summary>
/// Replace the contents of oldSession with the items
/// in newSession.
/// </summary>
/// <param name="newSession"></param>
/// <param name="oldSession"></param>
private void Replace(MdlSession newSession, MdlSession oldSession)
{
oldSession.Clear();
foreach (var key in newSession.Keys)
oldSession.Add(key, newSession[key]);
}
}