Accueil > .Net, Développement > Partage de sessions : Focus, State Server

Partage de sessions : Focus, State Server

Ce billet fait partie de la série « Partage de sessions » :

  1. Présentation
  2. Gestion native des sessions en .Net
  3. Focus, State Server (ce billet)
  4. Focus, SQL Server
  5. Focus, Couchbase
  6. Autres possibilités
  7. Conclusion
  8. Annexes

Dans ce billet, nous allons voir ce qu’est le State Server, ses avantages et inconvénients et comment le mettre en place.

 

Généralités

 

Dans le cas d’un State Server, la session est conserve dans un processus autre que celui de IIS (Out-of-Process ; et peut être sur une autre machine).
ASP .Net - State Server

L’une des architectures envisageable avec le State Server est la suivante :
ASP.Net - State Server - Architecture

Le State Server va garder les sessions en mémoire, ce qui veut dire que s’il doit gérer plusieurs applications Web, il faudra prévoir suffisamment de RAM.
Le cookie (ASP.NET_SessionId) sera toujours utilisé, côté utilisateur, pour conserver l’identifiant de session.

 

Avantages et inconvénients

 

Le premier avantage est d’être indépendant de IIS : si l’application (ou le pool ou même IIS) est recyclée (ou redémarrée), les sessions sont restaurées. Le second avantage est qu’il est possible de faire pointer plusieurs serveurs IIS vers le même State Server (cas du Load Balancing, par exemple).
Pour des questions à la fois de sécurité et de performances, il est préférable d’utiliser un serveur dans une DMZ non publique, où IIS ne sert pas de frontal Web. Un serveur applicatif est donc tout indiqué pour devenir un State Server.

Cependant, ces avantages sont contrebalancés par le fait de la sérialisation/désérialisation. Cela implique une légère surcharge pour les types primitifs (int, long, string…), mais surtout requiert de spécifier l’attribut « Serializable » sur toutes les classes. Si les structures chargées en sessions ne sont nativement pas sérialisable, il faudra alors ajouter du code pour les rendre sérialisable.
De plus, les sessions ne peuvent être hébergées que sur une seule machine, ce qui implique que son indisponibilité rendra les applicatifs web, de fait, inaccessibles. De même, si le serveur reboot, les sessions seront perdues du fait du stockage en mémoire.
Enfin, l’évènement du « Session_End » Global.asax ne sera jamais levé.

 

Configuration

 

Dans le Web.config, il faut faire plusieurs modifications.
La balise ApplicationName des appSettings permet d’identifier plusieurs applicatifs devant partager la session (j’y reviens un peu après).
Le machineKey doit également être identique sur tous les applicatifs.
Enfin, la balise sessionState permet de configurer le State Server. Dans l’exemple, il est en local.

<?xml version="1.0" encoding="utf-8"?>

<configuration>
  <appSettings>
    <add key="ApplicationName" value="ApplicationName"/>
  </appSettings>
  <system.web>
    <sessionState
      mode="StateServer"
      stateConnectionString="tcpip=127.0.0.1:42424" />

    <machineKey validationKey="EB9231989609C0587218913BD4A9CF56A51977A8DCAA04D224AB86581173BDB6A636FFCFC234669049C531EF9C4123883EE9DC509C3E8AE650166476D7FC1AE4"
      decryptionKey="41A0588A0553E66942683538425AF806BA1B89DA6AB70699"
      validation="SHA1"
    />
  </system.web>
  
</configuration>

 

Mise en place

 

De base, les applicatifs ne sont pas censé partager une même session et encore moins le même contenu.

Pour y parvenir, il faut modifier le nom de l’application en insérant du code dans le Global.asax :
Note : pour le State Server comme avec SQL Server, c’est le nom de l’application ET l’identifiant de session qui permettent de retrouver le contenu. Si l’un manque, c’est mort.

public class Global : HttpApplication
{
    public override void Init()
    {
        base.Init();

        foreach (string moduleName in Modules)
        {
            var appName = ConfigurationManager.AppSettings["ApplicationName"];
            var module = Modules[moduleName];
            var ssm = module as SessionStateModule;
            if (ssm == null) continue;

            var storeInfo = typeof(SessionStateModule)
                .GetField("_store", BindingFlags.Instance | BindingFlags.NonPublic);
            if (storeInfo == null) continue;

            var store = (SessionStateStoreProviderBase)storeInfo.GetValue(ssm);
            if (store == null)
            {
                var runtimeInfo = typeof(HttpRuntime)
                    .GetField("_theRuntime", BindingFlags.Static | BindingFlags.NonPublic);

                if (runtimeInfo != null)
                {
                    var theRuntime = (HttpRuntime)runtimeInfo.GetValue(null);
                    var appNameInfo = typeof(HttpRuntime)
                        .GetField("_appDomainAppId", BindingFlags.Instance | BindingFlags.NonPublic);
                    if (appNameInfo != null) appNameInfo.SetValue(theRuntime, appName);
                }
            }
            else
            {
                var storeType = store.GetType();
                if (storeType.Name.Equals("OutOfProcSessionStateStore"))
                {
                    var uribaseInfo = storeType
                        .GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic);
                    if (uribaseInfo != null) uribaseInfo.SetValue(storeType, appName);
                }
            }
        }
    }
}

Ensuite, il faut vérifier la disponibilité du service gérant le State Server.
Pour cela, il faut aller dans la console des services (services.msc) et trouver « ASP.Net State Service » ou « Service d’état ASP.Net », suivant la langue du système.
Une fois le service démarré, la mise en place est achevée, reste à l’utiliser.

 

Proof of Concept

 

L’application d’exemple est disponible.

Catégories :.Net, Développement

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :