Управление состоянием в ASP.NET
Страница 5. Серверные методы. Session


Session

Контейнер Session похож на Application, с той лишь разницей, что для каждого пользователя приложения создается своя собственная сессия со своими собственными значениями. Для идентификации пользователей ASP.NET использует 120-битный ключ, именуемый SessionID и состоящий только из ASCII-символов, которые допустимы для использования в URL. В зависимости от настроек веб-приложения, этот ключ сохраняется либо в Cookie либо включается как часть URL.

Если приложение настроено на использование URL для хранения SessionID, то написав в браузере, например, https://localhost/StateManagement/SessionStateTest.aspx, после загрузки страницы мы увидим вместо него нечто такое https://localhost/StateManagement/(evzobo45mp1rat55b3qm5o55)/SessionStateTest.aspx, где evzobo45mp1rat55b3qm5o55 - тот самый SessionID

При поступлении запроса от пользователя, у которого нет соответствующего Cookie или он не имеет SessionID в URL запроса, инициируется создание новой сессии. При этом происходит генерация нового уникального SessionID. После чего возникает событие Session_Start веб-приложения.

Сессия существует до тех пор, пока пользователь работает с веб-приложением и еще немного после. Для этого в настройках аппликации выставляется таймаут сессии, который по умолчанию составляет 20 минут. Т.е. если пользователь в течение 20 минут не совершил ни одного запроса к приложению, то сессия этого пользователя уничтожается. При этом возникает событие Session_End приложения.

Также как Application, для совместимости с предыдущими версиями ASP, контейнер включает в себя две коллекции Contents и StaticObjects. Для доступа к Contents можно либо использовать одноименное свойство, либо индексатор Session. Например:

// два эквивалентных способа доступа
// через индексатор Session
Session["Message"] = "My string";
Session["SessionStartTime"] = DateTime.Now;
string s = (string)Session["Message"];
DateTime startTime = (DateTime)Session["SessionStartTime"];
// через свойство Contents
Session.Contents["Message"] = "My string";
Session.Contents["SessionStartTime"] = DateTime.Now;
string s = (string)Session.Contents["Message"];
DateTime startTime = (DateTime)Session.Contents["SessionStartTime"];

Коллекция StaticObjects является read-only коллекцией, ее элементы определяются в файле Global.asax с помощью тега <object runat="server" scope="session">. Например:

<object runat="server" scope="session" id="SessionStr" class="System.Text.StringBuilder"/>

Использовать его можно аналогично вышеуказанному примеру для Application:

%3c%21-- в aspx файле --%3e
<form id="Form1" method="post" runat="server">
SessionStr value: <%= SessionStr %>
</form>
// в коде на C#
StringBuilder sb = (StringBuilder)Session.StaticObjects["SessionStr"];
sb.Append("My String");
Label1.Text = Session.StaticObjects["SessionStr"].ToString();

Механизм сессий, в отличие от Application, предоставляет несколько способов сохранения. Какой из них использовать в приложении, определяется атрибутом mode тега <sessionState> в файле web.config. Этот атрибут может принимать пять значений:

  • Off. Сессии отключены, т.е. данные сессии никак не сохраняются.

  • InProc. Способ, унаследованный от предыдущих версий ASP. Сессия храниться в локальной памяти веб-сервера. В результате при сбое приложения или перезапуске веб-сервера все данные теряются. Это может быть вызвано, например, настройками из тега <processModel> в файле machine.config (либо web.config). Один из возможных сценариев - преувеличение объема памяти, указанного в атрибуте memoryLimit. Поскольку каждый пользователь имеют свою собственную сессию, то увеличение нагрузки на сервер может потребовать достаточно большого объема ресурсов. Также перезапуск может вызвать изменение одного из файлов Global.asax или Web.config, либо директории \Bin приложения.

  • StateServer. Сохранение сессии в отдельном процессе на отдельном сервере. Для использования этого метода необходимо убедиться, что ASP.NET State Service запущен на удаленном сервере, который планируется использовать для хранения сессии. Этот сервис инсталлируется вместе с ASP.NET и Visual Studio .NET и может быть найден по такому пути:
    systemroot\Microsoft.NET\Framework\versionNumber\aspnet_state.exe
    В web.config необходимо в атрибуте connectionString указать название удаленного сервера и используемый порт. В результате web.config будет содержать подобную строку:

  • <sessionState
    mode="StateServer"
    stateConnectionString="tcpip=sessionserver:42424"
    cookieless="true"
    timeout="20"
    />

Этот способ защищает от проблем, связанных со сбоями веб-сервера. Кроме того, в случае развертывания приложения на нескольких серверах (web farm), предоставляет единую синхронизированную сессию для всех веб-серверов. С другой стороны, при возможном рестарте удаленного сервера, либо процесса ASP.NET State Service сессия все равно будет потеряна. Также необходимо учитывать, что при использовании данного способа все сохраняемые объекты должны быть сериализуемы.

 
« Предыдущая статья   Следующая статья »