我正在实施会话结构。
我在服务器端有ConcurrentDictionary
,持有所有<SessionId, UserSession>
对。
建立新连接时,会根据RememberMe
选项为客户端浏览器,perm或temp分配Cookie。
当客户端调用LogOut
函数时,它会从字典中删除会话。
但是,当客户端浏览器被简单关闭或崩溃,并且cookie丢失或过期或删除时,内存中的服务器端会话对象将保留在字典中并变为重影。随着时间的推移,这些鬼魂会堆积起来。
我的问题是,如何改进设计,以便在死亡会话过期后进行清理?
我考虑过让计时器服务运行一个清洁计划,但感觉并不优雅。是否有更简单的方法可以在不依赖外部服务的情况下执行此操作?
答案 0 :(得分:4)
我的一个项目中有类似的情况。
而不是字典,我使用短暂的绝对过期缓存和用户的会话ID作为我的缓存键:
HttpContext.Current.Cache.Insert(sessionID, userEntity, null, DateTime.Now.AddSeconds(30), TimeSpan.Zero);
在客户端,我每隔15秒进行一次ajax调用,通知服务器并更新该会话ID的缓存。
因此,每当用户关闭其浏览器窗口时,服务器都不会收到任何通知和用户的会话ID自动过期。
答案 1 :(得分:2)
如果你的会话状态是“InProc”,为什么不在Session_Start和Session_End中应用你的代码?
void Session_Start(object sender, EventArgs e)
{
//Add to ConcurrentDictionary
}
void Session_End(object sender, EventArgs e)
{
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.
//Remove from ConcurrentDictionary
}
答案 2 :(得分:0)
几个月后我回答了我自己的问题。如果我想拥有这样的结构,我会使用Microsoft SignalR。因为它以实时的方式为我控制会话并且做得更多。