Mini Kabibi Habibi

Current Path : C:/Users/Public/Documents/DXTREME 13.1 Demos/DXSK8/DXSK8.Service/
Upload File :
Current File : C:/Users/Public/Documents/DXTREME 13.1 Demos/DXSK8/DXSK8.Service/SessionConnectionProvider.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.EntityClient;
using System.Data.Metadata.Edm;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Web;

namespace DXSK8.Service {

    public static class SessionConnectionProvider {

        class SessionInfo {
            public EntityConnection EntityConnection;
            public DateTime LastUsed;
        }
        
        static readonly TimeSpan SessionTimeout = TimeSpan.FromMinutes(20);
        static readonly TimeSpan SessionCollectionInterval = TimeSpan.FromMinutes(10);
        static DateTime LastSessionCollectionTime = DateTime.Now;

        const string SessionCookieName = "DXSK8_UserID";
        static readonly object LockObject = new Object();
        
        static Dictionary<string, SessionInfo> Sessions = new Dictionary<string, SessionInfo>();
        static MetadataWorkspace Workspace = new MetadataWorkspace(new string[] { "res://*/" }, new Assembly[] { Assembly.GetExecutingAssembly() });


        static string SessionKeyFromCookie() {
            var cookie = HttpContext.Current.Request.Cookies[SessionCookieName];
            if(cookie != null)
                return cookie.Value;
            return null;                
        }

        static void SessionKeyToCookie(string key) {            
            HttpContext.Current.Response.SetCookie(new HttpCookie(SessionCookieName) {
                Expires = DateTime.Now.AddHours(1),
                Value = key,
                HttpOnly = true
            });                    
        }

        public static EntityConnection GetConnection() {
            lock(LockObject) {
                CollectStaleSessions();                

                var sessionKey = SessionKeyFromCookie();

                if(String.IsNullOrEmpty(sessionKey)) {
                    sessionKey = Guid.NewGuid().ToString();
                    SessionKeyToCookie(sessionKey);
                }

                SessionInfo session;
                if(Sessions.ContainsKey(sessionKey)) {
                    session = Sessions[sessionKey];
                } else {
                    session = Sessions[sessionKey] = new SessionInfo();
                }

                EntityConnection connection = session.EntityConnection;
                if(connection == null || connection.State == ConnectionState.Closed) {
                    if(connection != null)
                        connection.Dispose();
                    connection = session.EntityConnection = CreateEntityConnection();
                }

                session.LastUsed = DateTime.Now;
                return connection;
            }
        }
        
        static void CollectStaleSessions() {
            var now = DateTime.Now;
            if(now - LastSessionCollectionTime < SessionCollectionInterval)
                return;                        
            
            foreach(var key in new List<string>(Sessions.Keys)) {
                var session = Sessions[key];
                if(now - session.LastUsed > SessionTimeout) {
                    session.EntityConnection.Dispose();
                    Sessions.Remove(key);
                }                    
            }

            LastSessionCollectionTime = now;            
        }

        static EntityConnection CreateEntityConnection() {
            var sqlConnection = new SqlConnection();
            sqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings["DXSK8"].ToString();

            var entityConnection = new EntityConnection(Workspace, sqlConnection);
            entityConnection.Open();
            if(!HttpContext.Current.Request.RawUrl.Contains("RegisterNotificationChannel")) {
                entityConnection.BeginTransaction(IsolationLevel.Snapshot);
            }

            return entityConnection;
        }        

    }

}