📜 ⬆️ ⬇️

Writing Your ASP.NET Session Store Provider Using Redis

Greetings

In this article I would like to share the experience of writing your own Session Store Provider using Redis as a repository.

About Redis a lot has been written. But in short, Redis is a very fast storage in key-value format (and not only). It seems to me that it is very well suited for such tasks and I have long been interested in trying it in my project.
')
Also, for those who want to try the result in, I will give a link to the source.

Why is all this necessary?


It took me a session repository that meets the following requirements:

1. Control over the process of recording / reading session
I will explain later why.

2. Distribution between multiple application instances.
To scale the application to multiple servers.

3. Speed.
Everything is clear why.

Disclaimer

I’ll say right away that while this code at the prototype stage, made in my spare time, just see what happens. I did not decide to use it in the project or not, but I think the one described here will be interesting to someone. There is also a mercenary intent of this publication - maybe someone will point out the shortcomings of this approach, before I decide to use it in production :)

Redis I use almost a couple of hours myself, so there is probably something to improve (I will be glad to hear it in the comments).

The Redis installation process is omitted. I can say that I picked up Ubuntu Server on VirtualBox, and then it was a matter of several commands and editing several files (for a static IP and for allowing Redis to accept connections not only from localhost).

Also, I have to mention that there are already existing solutions, for example, Windows Server AppFabric Cache with its session provider, but due to point 1, you still need to write your provider (using only its functional cache), and in speed I think Redis will be faster.

Why you need your provider

The session is essentially a collection of key-value, this dictionary gets at the beginning of the request, and is recorded (in case of changes) at the end of the request.
If you have several requests that use the session , and not only read (read), but also change some values ​​in it, then these requests will not be executed in parallel . This is because in standard providers only one session can use an exclusive session (which is necessary for recording).

We have several blocks on each page that are loaded in parallel (AJAX), and in all we need access to the session (each block changes its variables). With any standard provider, they are executed one by one. And we need parallel.

Classes for implementing Session Store Provider

There are 2 main and 1 additional classes that you need to implement for your session provider.

  1. RedisNoLockSessionStateStoreProvider inherited from SessionStateStoreProviderBase. Responsible for “retrieving” a session (i.e. an entire collection) from the repository. Here it should be noted that at first I was always confused by the names of his methods: GetItem, RemoveItem, ... By names, you can decide that the class is responsible for individual objects in the session, but this is not so.

    In an implementation in which the elements of a session can be changed in several requests in parallel, this class takes almost nothing.
    Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    1. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    2. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    3. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    4. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    5. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    6. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    7. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    8. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    9. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    10. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    11. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    12. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    13. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    14. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    15. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    16. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    17. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    18. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    19. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    20. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    21. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    22. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }
    23. Copy Source | Copy HTML public class RedisNoLockSessionStateStoreProvider : SessionStateStoreProviderBase { //... public override SessionStateStoreData CreateNewStoreData(System.Web. HttpContext context, int timeout) { string sessionId = context.Request.Cookies[RedisNoLockSessionIDManager.CookieName].Value; return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (sessionId, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), timeout); } public override SessionStateStoreData GetItem(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { lockAge = TimeSpan .Zero; lockId = null ; locked = false ; actions = SessionStateActions .None; // RedisNoLockSessionStateItemsCollection return new SessionStateStoreData ( new RedisNoLockSessionStateItemsCollection (id, _defaultTimeout, _redisServer, _redisDb), SessionStateUtility.GetSessionStaticObjects(context), _defaultTimeout); } public override SessionStateStoreData GetItemExclusive(System.Web. HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this .GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //... }


  2. RedisNoLockSessionStateItemsCollection inherited from ISessionStateItemCollection is a class that implements everything necessary for accessing session elements. In the current implementation, he takes on almost all the work.
    I think from the code below it is clear how everything is arranged there. The idea is that each item is obtained and saved separately.

    Copy Source | Copy HTML
    1. public class RedisNoLockSessionStateItemsCollection : RedisSessionConfig , ISessionStateItemCollection
    2. {
    3. // ...
    4. public object this [ string name]
    5. {
    6. get
    7. {
    8. string key = GetKey (name);
    9. using ( var redis = SingleRedisPool.GetClient (_redisServer))
    10. {
    11. return redis.Get < object > (key);
    12. }
    13. }
    14. set
    15. {
    16. string key = GetKey (name);
    17. using ( var redis = SingleRedisPool.GetClient (_redisServer))
    18. {
    19. bool result = redis.Set < object > (key, value );
    20. }
    21. }
    22. }
    23. // ...
    24. }


  3. Well, the third class RedisNoLockSessionIDManager which is responsible for creating the session ID and writing a cookie, it is quite simple.
    Copy Source | Copy HTML
    1. public class RedisNoLockSessionIDManager : RedisSessionConfig , ISessionIDManager
    2. {
    3. public string CreateSessionID ( HttpContext context)
    4. {
    5. Return Guid .NewGuid (). ToString ( "N" );
    6. }
    7. public string GetSessionID ( HttpContext context)
    8. {
    9. var cookie = context.Request.Cookies.Get (CookieName);
    10. return cookie! = null ? cookie.Value: null ;
    11. }
    12. public bool InitializeRequest ( HttpContext context, bool suppressAutoDetectRedirect, out bool supportSessionIDReissue)
    13. {
    14. supportSessionIDReissue = false ;
    15. return false ;
    16. }
    17. public void SaveSessionID ( HttpContext context, string id, out bool redirected, out bool cookieAdded)
    18. {
    19. HttpCookie cookie = new HttpCookie (CookieName, id);
    20. cookie.Expires = DateTime .Now.Add (Configuration.Timeout);
    21. context.Response.Cookies.Add (cookie);
    22. redirected = false ;
    23. cookieAdded = true ;
    24. }
    25. public bool Validate ( string id)
    26. {
    27. return true ;
    28. }
    29. // ..
    30. }

That's all. The moments of getting configuration settings from web.config are omitted, but this part has a rather mediocre relation to the session itself; you can see this part in the source code.

Conclusion

A few things I would like to say in conclusion.

I will be glad to hear your comments. Thanks for attention.

Source: https://habr.com/ru/post/123812/


All Articles