Сохранение сеанса в БД - PullRequest
       6

Сохранение сеанса в БД

0 голосов
/ 07 февраля 2012

Мой архитектор интересуется, почему мы должны сохранять сеанс каждого пользователя в БД, а не просто использовать куки. Я никогда не видел, чтобы кто-то использовал только куки.

Обычно я сохраняю идентификатор сеанса в файле cookie, а затем использую его для выполнения CRUDS для записи сеанса, связанной с идентификатором.

Я имею в виду, я не понимаю, как вы можете сделать состояние сеанса без в proc. Я всегда выполнял состояние сеанса через пользовательскую таблицу, содержащую стандартные поля, такие как 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, принудительно закрывать их сеанс и все виды вещей на основе их текущего сеанса.

Также в нашем Application_Error в global.asax мы регистрируем текущий идентификатор сессии для целей отслеживания ошибок.

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);
}

1 Ответ

2 голосов
/ 07 февраля 2012

Сеанс ASP.NET имеет 3 возможных состояния:

  • Выкл. (Мое предпочтение) - вообще не использовать сессии
  • InProc - сеанс хранится в памяти веб-сервера. Быстро, но не удобно, если вы работаете в веб-ферме, потому что каждый узел веб-фермы будет иметь свою копию сеанса, и вы можете столкнуться с конфликтами.
  • Out-of-Proc - сеанс хранится в памяти специально выделенного сервера, на котором запущена служба Windows состояния сеанса ASP.NET. Подходит для сценариев веб-фермы, но недостаточно надежен, поскольку сеанс все еще сохраняется в памяти какого-либо сервера, который может не выдержать сбоев.
  • SQL Server - сеанс сохраняется на SQL-сервере. Очень надежный и подходящий для веб-ферм. Проблема с производительностью. Это будет медленнее, чем в предыдущих режимах, поскольку сеанс теперь сохраняется в базе данных.

3 режима подробно описаны в следующей статье .

Выбранный вами режим настраивается в web.config, и он полностью прозрачен для вашего кода, в котором вы просто используете Session["someKey"] для работы с сеансом, это просто базовый механизм хранения, который отличается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...