# Session Management

Wisej.NET provides comprehensive session management - among the most complete server-side state management systems compared to other web frameworks.

## Web Session Basics

Web systems are inherently stateless:

* Each browser request may be processed by different server threads
* Server threads can be reused across browsers
* Session management requires generating and tracking session IDs with each request

Wisej.NET fully supports server-side state management for both HTTP and WebSocket connections.

{% hint style="info" %}
Contrast this with other frameworks:

* Blazor lacks native state management - refreshing loses all work
* Angular, React and similar client-side libraries don't support sessions
* ASP.NET offers limited HTTP-only session control (not WebSocket compatible) using shared cookies
  {% endhint %}

## Understanding Sessions

Important distinctions:

* Sessions differ from users and authentication
* Web sessions parallel desktop application instances
* Desktop apps can run with/without users/authentication
* Multiple instances create separate sessions
* Web apps don't run separate executables per session
* No dedicated UI thread exists
* Each request independently restores session state

## Session Challenges

Web applications face unique session management challenges:

* Browser and server on different machines
* Intermittent connectivity
* Users leaving browsers open
* Unexpected shutdowns
* Navigation between pages
* Browser refresh/F5

Sessions must survive some events while terminating for others. With no reliable way to detect browser closure, device shutdown, or distinguish navigation from tab closure, Wisej.NET uses:

* [Keep-alive](#undefined) pings
* Session [timeout](#timeout)

## Timeout

Wisej.NET removes a session from memory after a period without user activity signs. The [`sessionTimeout`](https://docs.wisej.com/docs/configuration#default.json) setting determines when Wisej.NET fires the [`Application.SessionTimeout`](https://docs.wisej.com/api/wisej.web/general/application#sessiontimeout) event.

{% hint style="danger" %}
When a session times out, it's permanently removed - like terminating a desktop application. ASP.NET's `Session_End` handler in Global.asax fires after session removal, allowing only cleanup.
{% endhint %}

This event provides an opportunity to react before losing the session and user's work. By default, without handling [`Application.SessionTimeout`](https://docs.wisej.com/api/wisej.web/general/application#sessiontimeout), Wisej.NET displays a built-in [countdown window](#countdown-window).

After another timeout period without user response, Wisej.NET removes the session and fires [`Application.ApplicationExit`](https://docs.wisej.com/api/wisej.web/general/application#applicationexit).

### Keep-Alive

Beyond `sessionTimeout`, Wisej.NET employs a keep-alive ping system that triggers after periods of user inactivity. This helps detect when users are "gone" due to:

* Closed browser
* Powered-off device
* Lost connectivity

With no user activity but an open browser, the client sends keep-alive messages. Without these messages, Wisej.NET terminates the session after `sessionTimeout * 2`.

### Countdown Window

After `sessionTimeout` seconds without user interaction, Wisej.NET:

1. Fires [`Application.SessionTimeout`](https://docs.wisej.com/api/wisej.web/general/application#sessiontimeout)
2. Shows built-in `SessionTimeoutForm` if unhandled

<div align="left"><img src="https://553579532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MF1D11gPs_az3xaKusw%2Fuploads%2Fgit-blob-d40f0f481cfc99b696f2570c988a4e1393a4b968%2Fimage.png?alt=media" alt="Default timeout window."></div>

You can:

* Show a custom window
* Extend `SessionTimeoutForm`
* Show nothing by setting `e.Handled = true`

{% tabs %}
{% tab title="C#" %}

```csharp
Application.SessionTimeout += Application_SessionTimeout;

private static void Application_SessionTimeout(object sender, System.ComponentModel.HandledEventArgs e)
{
    // do something
    
    // suppress the built-in timeout window.
    e.Handled = true;
}
```

{% endtab %}

{% tab title="VB.NET" %}

```visual-basic
AddHandler Application.SessionTimeout, AddressOf Application_SessionTimeout

Public Sub Application_SessionTimeout(sender As Object, e As HandledEventArgs)

    ' Do something.
    
    ' Suppress the built-in timeout window.
    e.Handled = True

End Sub
```

{% endtab %}
{% endtabs %}

### Infinite Sessions

Wisej.NET supports two types of infinite sessions:

1. **Standard Infinite**
   * Suppress the timeout window
   * Session stays alive while browser is open and connected
   * See above for suppressing timeout window

{% hint style="success" %}
Best practice: Set `sessionTimeout` to 1-3 minutes (60-180 seconds) and handle `Application.SessionTimeout` to control expiration notices or suppress them entirely.
{% endhint %}

2. **Browser-Bound Sessions**
   * Bind session to browser by saving Session ID to local storage
   * Optionally set `sessionTimeout` to 0 (never expires until server shutdown)
   * Users can return later to continue where they left off
   * Requires controlled session count

## Session ID Storage

Traditional HTML systems (PHP, ASP.NET, JSP) store session IDs in cookies that:

* Persist after browser closure
* Share across browser tabs
* Limit to one session per browser

Wisej.NET offers two storage options:

### Session Storage (Default)

Wisej.NET defaults to browser [Session Storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage):

* Cleared when browser closes
* Not sent in request headers
* Unique per browser tab

{% hint style="info" %}
Closing the browser removes the session.
{% endhint %}

### Local Storage

Optionally [configure](https://docs.wisej.com/docs/configuration#default.json) Wisej.NET to use browser [Local Storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage):

* Survives browser closure/device shutdown
* Session reloads automatically if not expired
* Continues work from previous state

## Session Termination

Various scenarios affect session termination:

### Application Exit

If your application provides exit options, call [`Application.Exit()`](https://docs.wisej.com/api/wisej.web/general/application#exit) to:

* Free the session immediately
* Fire [`Application.ApplicationExit`](https://docs.wisej.com/api/wisej.web/general/application#applicationexit)

### Browser Events

These scenarios stop keep-alive pings, triggering session termination after `sessionTimeout` \* 2:

* Closing browser tab
* Closing entire browser
* Navigating away
* Device shutdown

{% hint style="info" %}
Browsers provide no way to distinguish between navigation, closure, shutdown, or device destruction. All appear the same to the server.
{% endhint %}
