133 lines
3.5 KiB
C#
133 lines
3.5 KiB
C#
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]);
|
|
}
|
|
}
|