2012-02-06 87 views
0

我的架构师想知道为什么我们需要将每个用户的会话保存到数据库而不是仅仅使用cookie。我从来没有见过任何人使用cookie。坚持会话到数据库

通常,我将会话ID保存在一个cookie中,然后使用它在会话记录上执行CRUDS,从而将ID删除。

我的意思是我没有看到如何在没有进程的情况下执行会话状态。我一直通过一个自定义表格来保存会话状态,例如IsLoggedIn,IsClosed,IsNew,IPAddress,Browser等等。

有没有人在电子商务网站上完成会话状态而没有将其保存在数据库中?

修订

因此,这里是有点我们如何在另一个地方,我在一家拿到500+页的电子商务网站做的事情命中一个月:

public USession CreateNewSession(int userID) 
{ 
    string ipAddress = GetCurrentRequestIPAddress(context.Request); 

    USession newSession = USession.NewSession(); 
    newSession.IpAddress = ipAddress; 
    newSession.UserID = customerID; 
    newSession.Browser = context.Request.UserAgent ?? string.Empty; 

    if (context.Request.UrlReferrer != null) 
    newSession.Referer = context.Request.UrlReferrer.ToString(); 
    else 
    newSession.Referer = string.Empty; 

    InsertSession(newSession); 

    return newSession; 
} 



public USession CreateNewSession(int userID) 
{ 
    string ipAddress = GetCurrentRequestIPAddress(context.Request); 

    USession newSession = USession.NewSession(); 
    newSession.IpAddress = ipAddress; 
    newSession.UserID = customerID; 
    newSession.Browser = context.Request.UserAgent ?? string.Empty; 

    if (context.Request.UrlReferrer != null) 
     newSession.Referer = context.Request.UrlReferrer.ToString(); 
    else 
     newSession.Referer = string.Empty; 

    InsertSession(newSession); 

    return newSession; 
} 



public USession GetSession() 
{ 
    // existing sessionId this session? 
    HttpCookie cookie = context.Request.Cookies["usessionId"]; 

    if (cookie == null || string.IsNullOrEmpty(cookie.Value)) 
    session = CreateNewSession(0); 
    else 
    { 
     string sessionID = cookie.Value; 

     session = GetSession(sessionID); 

     if (session == null) 
      session = CreateNewSession(0); 
     else if (session.IsClosed > 0) 
      session = CreateNewSession(session.UserID); 
    } 

    if (session.LastAccessed < DateTime.Now.AddHours(-1)) session.LoggedIn = false; 

    if (session.LastDestination.Equals("lesson")) 
     session.LastDestPageDestinationID = ContextValue(context, "lessonid"); 
    else 
     session.LastDestPageDestinationID = 0; 

    if (session.IsNew) session.FirstDestination = session.LastDestination; 

    SaveSession(); 

    return session; 
} 



private void SaveSession() 
{ 
    session.LastAccess = DateTime.Now; 
    session.LastDest = string.Empty; 

    db.UpdateSession(session); 

    if (!cookieIsSet) 
    { 
     // add a session cookie for this current session 
     HttpCookie cookie = CreateSessionCookie("usessionId", session.SessionID, 365); 

     if (session.LastDest.Equals("logout", StringComparison.OrdinalIgnoreCase)) 
      cookie.Value = string.Empty; 

     if (session.LastDest.Equals("lessonOrder")) return; 

     context.Response.SetCookie(cookie); 
    } 
} 


internal void UpdateSession(USession s) 
{ 
    using (ourConnection conn = CreateConnection("UpdateSession")) 
    { 
     conn.CommandText = @"update csession set 
      closed = @closed, 
      userID = @customerID, 
      lastAccess = @lastAccess, 
      lastDestination = @lastDest, 
         orderId = @OrderId, 
      IsloggedIn = @isLoggedIn; 

     conn.AddParam("@id", s.Id); 
     conn.AddParam("@closed", s.Closed); 
     conn.AddParam("@userID", s.UserID); 
     conn.AddParam("@lastAccess", s.LastAccess); 
     conn.AddParam("@firstDestination", s.FirstDestination); 
     conn.AddParam("@lastDestination", s.LastDestination); 
     conn.AddParam("@isLoggedIn", s.IsLoggedIn); 
     conn.AddParam("@orderID", s.OrderID); 

     try 
     { 
      conn.ExecuteNonQuery(); 

     } 
     catch (Exception ex) 
     { 
      LogException(ex); 
     } 
    } 
} 


public HttpCookie CreateSessionCookie(string cookieValue, string uSessionID, double daysTillExpiration) 
{ 
    HttpCookie cookie = new HttpCookie("usessionid", uSessionID); 
    cookie.Expires = DateTime.Now.AddDays(daysTillExpiration); 
    cookie.Path = "/"; 

    return cookie; 
} 

因此我们在我们的代码中使用USession自定义对象来检查loggedIn,强制关闭他们的会话,以及基于他们当前会话的各种东西。

同样在我们在global.asax中的Application_Error中,我们会记录当前sessionId,以便在出错时进行跟踪。

HttpCookie cookie = Request.Cookies["usessionid"]; 
if (cookie != null) 
{ 
    logger.Variables = "<b>uSessionID:</b> " + cookie.Value; 

    if (cookie.Value.Length > 0) 
     logger.USessionID = GetUSessionID(cookie.Value); 
} 

回答

2

ASP.NET会话有3种可能的状态:

  • 关(我的首选) - 会话存储在内存 - 在所有
  • InProc方式不使用任何会议Web服务器。如果您在Web场中运行,则速度很快但不方便,因为Web场的每个节点都有不同的会话副本,并且可能会发生冲突。
  • Out-of-Proc - 会话存储在运行ASP.NET会话状态Windows服务的特殊专用服务器的内存中。适用于webfarms场景,但不够可靠,因为会话仍然存在于某些可能无法应对崩溃的服务器的内存中。
  • SQL Server - 会话在SQL服务器中保存。非常可靠,适合网络农场。问题在于性能。由于会话现在保存在数据库中,因此会比以前的模式慢。

3种模式在following article中有详细介绍。

您选择的模式是在web.config中配置的,它对您的代码完全透明,您只需使用Session["someKey"]来处理会话,它只是不同的底层存储机制。

+0

是的,所以你不能只基于cookie的会话。我曾经在电子商务网站上工作,他们在一个月内获得了500,000次页面浏览量,而没有性能问题,使用自定义会话表并使用它来检查会话状态或为用户创建新的会话记录。 – PositiveGuy 2012-02-06 23:43:51

+0

为什么你会议完全关闭?你必须检查身份验证等,并拉动诸如他们的IPAddress,Referer进行日志记录等等,其中包括确定会话是否已经过期或在某些情况下明确关闭会话等。 – PositiveGuy 2012-02-06 23:44:21

+0

@CoffeeAddict,不管在您选择的3种持续模式中,会话默认由cookie(3种模式)跟踪。 – 2012-02-06 23:44:56