Beispiel #1
0
        /// <summary>
        /// Обобщенный вспомогательный метод для получения доступа к сессии в базе данных.
        /// Используется как GetItem, так и GetItemExclusive.
        /// </summary>
        private SessionStateStoreData GetSessionItem(HttpContext context, string id, bool exclusive, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
        {
            locked  = false;
            lockAge = new TimeSpan();
            lockId  = null;
            actions = 0;

            var sessionItem = TraceSessionStorage.GetSessionItem(id);

            // Сессия не найдена
            if (sessionItem == null)
            {
                return(null);
            }

            // Сессия найдена, но заблокирована
            if (sessionItem.Locked)
            {
                locked  = true;
                lockAge = DateTime.UtcNow - sessionItem.LockDate;
                lockId  = sessionItem.LockId;
                return(null);
            }

            // Сессия найдена, требуется эксклюзинвый доступ.
            if (exclusive)
            {
                lock (sessionItem.SyncRoot)
                {
                    sessionItem.LockId         += 1;
                    sessionItem.Locked          = true;
                    sessionItem.LockDate        = DateTime.UtcNow;
                    sessionItem.DateLastChanged = DateTime.Now;
                    TraceSessionStorage.MarkSessionUpdated(sessionItem);
                }
            }

            locked  = exclusive;
            lockAge = DateTime.UtcNow - sessionItem.LockDate;
            lockId  = sessionItem.LockId;

            var data = (sessionItem.ItemContent == null)
                ? CreateNewStoreData(context, _timeoutSession)
                : Deserialize(context, sessionItem.ItemContent, _timeoutSession);

            data.Items["UserId"] = sessionItem.IdUser;

            return(data);
        }
Beispiel #2
0
        /// <summary>
        /// Удаляет запись о состоянии сессии.
        /// </summary>
        public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
        {
            var sessionItem = TraceSessionStorage.GetSessionItem(id);

            lock (sessionItem.SyncRoot)
            {
                if (sessionItem.LockId != (int)lockId)
                {
                    return;
                }

                sessionItem.DateLastChanged = DateTime.Now;
                TraceSessionStorage.RemoveSession(sessionItem);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Сохраняем состояние сессии и снимаем блокировку.
        /// </summary>
        public override void SetAndReleaseItemExclusive(HttpContext context,
                                                        string id,
                                                        SessionStateStoreData item,
                                                        object lockId,
                                                        bool newItem)
        {
            context.Items[InternalStoreInfo.KEY] = null;

            var intLockId = lockId == null ? 0 : (int)lockId;
            var userId    = (int)item.Items["UserId"];

            var data = ((SessionStateItemCollection)item.Items);

            data.Remove("UserId");

            // Сериализуем переменные
            var itemContent = Serialize(data);

            // Если это новая сессия, которой еще нет в базе данных.
            if (newItem)
            {
                CreateUninitializedItem(context, id, _timeoutSession);
                //return;//Не выходим из функции, т.к. в новую сессию еще надо записать данные.
            }

            // Если это старая сессия, проверяем совпадает ли ключ блокировки,
            // а после сохраняем состояние и снимаем блокировку.
            var sessionItem = TraceSessionStorage.GetSessionItem(id);

            if (sessionItem != null)
            {
                lock (sessionItem.SyncRoot)
                {
                    if (lockId == null || sessionItem.LockId == (int)lockId)
                    {
                        sessionItem.IdUser          = userId;
                        sessionItem.ItemContent     = itemContent;
                        sessionItem.Expires         = DateTime.UtcNow.AddMinutes(_timeoutSession);
                        sessionItem.Locked          = false;
                        sessionItem.DateLastChanged = DateTime.Now;
                        if (!newItem || (newItem && itemContent != null))
                        {
                            TraceSessionStorage.MarkSessionUpdated(sessionItem);
                        }
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Создание пустой записи о новой сессии в хранилище сессий.
        /// </summary>
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var session = new UserSession
            {
                SessionId   = id,
                IdUser      = 0,
                Created     = DateTime.UtcNow,
                Expires     = DateTime.UtcNow.AddMinutes(timeout),
                LockDate    = DateTime.UtcNow,
                Locked      = false,
                ItemContent = null,
                LockId      = 0,
            };

            TraceSessionStorage.AddSession(session);
        }
Beispiel #5
0
        /// <summary>
        /// Удаляем блокировку сессии, освобождаем ее для других потоков.
        /// </summary>
        public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
        {
            var sessionItem = TraceSessionStorage.GetSessionItem(id);

            if (sessionItem.LockId != (int)lockId)
            {
                return;
            }

            lock (sessionItem.SyncRoot)
            {
                sessionItem.Locked          = false;
                sessionItem.Expires         = DateTime.UtcNow.AddMinutes(_timeoutSession);
                sessionItem.DateLastChanged = DateTime.Now;
                TraceSessionStorage.MarkSessionUpdated(sessionItem);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Сбрасывает счетчик жизни сессии.
        /// </summary>
        public override void ResetItemTimeout(HttpContext context, string id)
        {
            var sessionItem = TraceSessionStorage.GetSessionItem(id);

            if (sessionItem == null)
            {
                return;
            }

            lock (sessionItem.SyncRoot)
            {
                // Обновляем время жизни только если есть данные в сессии. Пустым сессиям положено умирать.
                if (sessionItem.ItemContent != null)
                {
                    sessionItem.Expires         = DateTime.UtcNow.AddMinutes(_timeoutSession);
                    sessionItem.DateLastChanged = DateTime.Now;
                    TraceSessionStorage.MarkSessionUpdated(sessionItem);
                }
            }
        }