using System.Net; namespace SummerBestWebForm2.SessionState; // INTERFACE public interface ISessionManager { Task GetSession(); Task UpdateSession(MdlSession session); } // CODE /// /// Dictionary containing per-user session objects, keyed /// by sessionId. /// public class SessionManager : ISessionManager { private Dictionary _sessions = new Dictionary(); private readonly ISessionIdManager _sessionIdManager; private object syncLock1 = new(); public SessionManager(ISessionIdManager sessionIdManager) { _sessionIdManager = sessionIdManager; } public async Task 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(); 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 /// /// Replace the contents of oldSession with the items /// in newSession. /// /// /// private void Replace(MdlSession newSession, MdlSession oldSession) { oldSession.Clear(); foreach (var key in newSession.Keys) oldSession.Add(key, newSession[key]); } }