Sometimes it is sensible to maintain a little bit of client state between calls, even if your application is designed for Statelessness. For example, you might want to implement access control and provide a Login method to initiate authentication, rather than retransmitting the password for each and every remote call. This can be achieved through so called Sessions that allow you to store per-client information outside of your service objects. It will be up to your service implementation to store this data inside the session before a call finishes, and obtain it again, when needed, in subsequent calls.
Remoting SDK passes a so called Client ID (sometimes also referred to as Session ID) back and forth for each call made from a client to the server. This client ID is a GUID that uniquely identifies each client and allows the server to determine which calls are received from the same client.
Sessions can be used to store data for a specific client ID and later retrieve the same data again. To make this easy, the base classes for new services (RemObjects.SDK.Server.Service for .NET and TRORemoteDataModule for Delphi) encapsulate the communication with the underlying session manager and expose properties to check if session data exists, and to store and retrieve data from the session.
Session data is stored and maintained by a global Session Manager instance. Different implementations of session managers are provided to suit different needs, for example to store session data in memory or a back-end database:
- In-Memory Session Manager - stores session data in local memory within the application server. This provides fast access, but does not allow to persist session information when the server is restarted, or to share common session data by a server farm.
- Database Session Manager - stores session data in a database table accessible via ADO.NET, a Delphi TDataSet component or a Data Abstract server.
This allows sharing of session data between servers, and keeps session information persisted across server restarts (currently Delphi-only).
Event-Driven Session Manager - provides an easy way to use custom code to manually store and retrieve session data (currently Delphi-only).
Olympia Session Manager - provides a dedicated and ready-made server application that can store shared session data and push events. As Olympia is internally built upon Data Abstract for .NET it allows to talk to any database you choose or use pre-configured internal SQLite based storage in order to run out-of-the-box with zero setup and configuration.
The session manager architecture is flexible and extensible, allowing you to easily implement custom session managers to suit your specific needs, if necessary.
Application servers are usually intended to run continuously 24/7, without ever shutting down. As such, session memory would continue to grow slowly but steadily over the lifetime of a server, as new clients connect and disconnect. What's more, in most scenarios client applications will not maintain their unique client ID across restarts (although such functionality is possible, if required), so each restarted client will create a new session.
To avoid the server memory (or session database) filling up with stale and unused session data, Session Managers implement automatic session timeouts. The session managers keep track of sessions as they are accessed, and will destroy any session that has not been accessed for a given amount of time (by default 20 minutes).
Client applications that are expected to run longer periods of time without communication with the server should either implement regular "keep-alive" server calls to keep the session from expiring or - preferred - handle expired sessions gracefully, for example by handling the OnLoginNeeded event on the channels.