7

我正在实现一个会话结构。

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

当建立新连接时,cookie 将分配给客户端浏览器,perm 或 temp 取决于RememberMe选项。

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

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

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

我想过做一个定时服务来运行清洁计划,但感觉并不优雅。有没有更简单的方法可以在不依赖外部服务的情况下做到这一点?

4

3 回答 3

5

我的一个项目中有类似的情况。

我没有使用字典,而是使用具有较短绝对到期时间和用户会话 ID 的缓存作为我的缓存键:

HttpContext.Current.Cache.Insert(sessionID, userEntity, null, DateTime.Now.AddSeconds(30), TimeSpan.Zero);

在客户端,我每 15 秒进行一次 ajax 调用,以通知服务器并更新该会话 ID 的缓存。

因此,每当用户关闭其浏览器窗口时,服务器不会收到任何通知,并且用户的会话 ID 会自动过期。

于 2013-09-29T08:02:10.013 回答
3

如果您的会话状态是“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
}
于 2013-09-29T08:22:11.580 回答
1

几个月后我正在回答我自己的问题。如果我想拥有这样的结构,我会使用 Microsoft SignalR。因为它以实时方式为我控制会话并且做得更多。

于 2013-09-29T06:53:26.963 回答