如何处理会话保持开放状态

时间:2013-09-27 23:02:40

标签: c# asp.net-mvc .net-4.5 asp.net-session

我正在实施会话结构。

我在服务器端有ConcurrentDictionary,持有所有<SessionId, UserSession>对。

建立新连接时,会根据RememberMe选项为客户端浏览器,perm或temp分配Cookie。

当客户端调用LogOut函数时,它会从字典中删除会话。

但是,当客户端浏览器被简单关闭或崩溃,并且cookie丢失或过期或删除时,内存中的服务器端会话对象将保留在字典中并变为重影。随着时间的推移,这些鬼魂会堆积起来。

我的问题是,如何改进设计,以便在死亡会话过期后进行清理?

我考虑过让计时器服务运行一个清洁计划,但感觉并不优雅。是否有更简单的方法可以在不依赖外部服务的情况下执行此操作?

3 个答案:

答案 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。因为它以实时的方式为我控制会话并且做得更多。