Redis提供商配置ASP.NET会话状态
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Specialized;
using System.Web.SessionState;
using ServiceStack.Redis;
using System.Configuration;
using System.Configuration.Provider;
using System.Web.Configuration;
using System.IO; namespace RedisProvider.SessionProvider
{ #region Session Item Model
public class SessionItem
{ #region Properties
public DateTime CreatedAt { get; set; }
public DateTime LockDate { get; set; }
public int LockID { get; set; }
public int Timeout { get; set; }
public bool Locked { get; set; }
public string SessionItems { get; set; }
public int Flags { get; set; }
#endregion Properties }
#endregion Session Item Model public class CustomServiceProvider : System.Web.SessionState.SessionStateStoreProviderBase, IDisposable
{ #region Properties
private string ApplicationName
{
get
{
if (ConfigurationManager.AppSettings.AllKeys.Contains("Application.Name"))
{
return ConfigurationManager.AppSettings["Application.Name"];
} return string.Empty;
}
} private RedisClient RedisSessionClient
{
get
{ if (!string.IsNullOrEmpty(this.redisPassword))
{
return new RedisClient(this.redisServer, this.redisPort, this.redisPassword);
} return new RedisClient(this.redisServer, this.redisPort);
}
} private string redisServer = "localhost";
private int redisPort = ;
private string redisPassword = string.Empty;
private SessionStateSection sessionStateConfig = null;
private bool writeExceptionsToLog = false;
#endregion Properties #region Private Methods
/// <summary>
/// Prepends the application name to the redis key if one exists. Querying by application name is recommended for session
/// </summary>
/// <param name="id">The session id</param>
/// <returns>Concatenated string applicationname:sessionkey</returns>
private string RedisKey(string id)
{
return string.Format("{0}{1}", !string.IsNullOrEmpty(this.ApplicationName) ? this.ApplicationName + ":" : "", id);
}
#endregion Private Methods #region Constructor
public CustomServiceProvider()
{ }
#endregion Constructor #region Overrides
public override void Dispose()
{ } public override void Initialize(string name, NameValueCollection config)
{ // Initialize values from web.config.
if (config == null)
{
throw new ArgumentNullException("config");
} if (name == null || name.Length == )
{
name = "RedisSessionStateStore";
} if (String.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "Redis Session State Provider");
} // Initialize the abstract base class.
base.Initialize(name, config); // Get <sessionState> configuration element.
Configuration cfg = WebConfigurationManager.OpenWebConfiguration(ApplicationName);
sessionStateConfig = (SessionStateSection)cfg.GetSection("system.web/sessionState"); if (config["writeExceptionsToEventLog"] != null)
{
if (config["writeExceptionsToEventLog"].ToUpper() == "TRUE")
this.writeExceptionsToLog = true;
} if (config["server"] != null)
{
this.redisServer = config["server"];
} if (config["port"] != null)
{
int.TryParse(config["port"], out this.redisPort);
} if (config["password"] != null)
{
this.redisPassword = config["password"];
}
} public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
{
return true;
} public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
{
using (RedisClient client = this.RedisSessionClient)
{
// Serialize the SessionStateItemCollection as a string.
string sessionItems = Serialize((SessionStateItemCollection)item.Items); try
{
if (newItem)
{
SessionItem sessionItem = new SessionItem();
sessionItem.CreatedAt = DateTime.UtcNow;
sessionItem.LockDate = DateTime.UtcNow;
sessionItem.LockID = ;
sessionItem.Timeout = item.Timeout;
sessionItem.Locked = false;
sessionItem.SessionItems = sessionItems;
sessionItem.Flags = ; client.Set<SessionItem>(this.RedisKey(id), sessionItem, DateTime.UtcNow.AddMinutes(item.Timeout));
}
else
{
SessionItem currentSessionItem = client.Get<SessionItem>(this.RedisKey(id));
if (currentSessionItem != null && currentSessionItem.LockID == (int?)lockId)
{
currentSessionItem.Locked = false;
currentSessionItem.SessionItems = sessionItems;
client.Set<SessionItem>(this.RedisKey(id), currentSessionItem, DateTime.UtcNow.AddMinutes(item.Timeout));
}
}
}
catch (Exception e)
{
throw e;
}
}
} public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
return GetSessionStoreItem(true, context, id, out locked, out lockAge, out lockId, out actions);
} public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
{
return GetSessionStoreItem(false, context, id, out locked, out lockAge, out lockId, out actionFlags);
} private SessionStateStoreData GetSessionStoreItem(bool lockRecord,
HttpContext context,
string id,
out bool locked,
out TimeSpan lockAge,
out object lockId,
out SessionStateActions actionFlags)
{ // Initial values for return value and out parameters.
SessionStateStoreData item = null;
lockAge = TimeSpan.Zero;
lockId = null;
locked = false;
actionFlags = ; // String to hold serialized SessionStateItemCollection.
string serializedItems = ""; // Timeout value from the data store.
int timeout = ; using (RedisClient client = this.RedisSessionClient)
{
try
{
if (lockRecord)
{
locked = false;
SessionItem currentItem = client.Get<SessionItem>(this.RedisKey(id)); if (currentItem != null)
{
// If the item is locked then do not attempt to update it
if (!currentItem.Locked)
{
currentItem.Locked = true;
currentItem.LockDate = DateTime.UtcNow;
client.Set<SessionItem>(this.RedisKey(id), currentItem, DateTime.UtcNow.AddMinutes(sessionStateConfig.Timeout.TotalMinutes));
}
else
{
locked = true;
}
}
} SessionItem currentSessionItem = client.Get<SessionItem>(this.RedisKey(id)); if (currentSessionItem != null)
{
serializedItems = currentSessionItem.SessionItems;
lockId = currentSessionItem.LockID;
lockAge = DateTime.UtcNow.Subtract(currentSessionItem.LockDate);
actionFlags = (SessionStateActions)currentSessionItem.Flags;
timeout = currentSessionItem.Timeout;
}
else
{
locked = false;
} if (currentSessionItem != null && !locked)
{
// Delete the old item before inserting the new one
client.Remove(this.RedisKey(id)); lockId = (int?)lockId + ;
currentSessionItem.LockID = lockId != null ? (int)lockId : ;
currentSessionItem.Flags = ; client.Set<SessionItem>(this.RedisKey(id), currentSessionItem, DateTime.UtcNow.AddMinutes(sessionStateConfig.Timeout.TotalMinutes)); // If the actionFlags parameter is not InitializeItem,
// deserialize the stored SessionStateItemCollection.
if (actionFlags == SessionStateActions.InitializeItem)
{
item = CreateNewStoreData(context, );
}
else
{
item = Deserialize(context, serializedItems, timeout);
}
}
} catch (Exception e)
{
throw e;
}
} return item;
} public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
{ using (RedisClient client = this.RedisSessionClient)
{
SessionItem currentSessionItem = client.Get<SessionItem>(this.RedisKey(id)); if (currentSessionItem != null && (int?)lockId == currentSessionItem.LockID)
{
currentSessionItem.Locked = false;
client.Set<SessionItem>(this.RedisKey(id), currentSessionItem, DateTime.UtcNow.AddMinutes(sessionStateConfig.Timeout.TotalMinutes));
}
}
} public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
{
using (RedisClient client = this.RedisSessionClient)
{
// Delete the old item before inserting the new one
client.Remove(this.RedisKey(id));
}
} public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
{
using (RedisClient client = this.RedisSessionClient)
{
SessionItem sessionItem = new SessionItem();
sessionItem.CreatedAt = DateTime.Now.ToUniversalTime();
sessionItem.LockDate = DateTime.Now.ToUniversalTime();
sessionItem.LockID = ;
sessionItem.Timeout = timeout;
sessionItem.Locked = false;
sessionItem.SessionItems = string.Empty;
sessionItem.Flags = ; client.Set<SessionItem>(this.RedisKey(id), sessionItem, DateTime.UtcNow.AddMinutes(timeout));
}
} public override SessionStateStoreData CreateNewStoreData(System.Web.HttpContext context, int timeout)
{
return new SessionStateStoreData(new SessionStateItemCollection(),
SessionStateUtility.GetSessionStaticObjects(context),
timeout);
} public override void ResetItemTimeout(HttpContext context, string id)
{ using (RedisClient client = this.RedisSessionClient)
{
try
{
// TODO :: GET THIS VALUE FROM THE CONFIG
client.ExpireEntryAt(id, DateTime.UtcNow.AddMinutes(sessionStateConfig.Timeout.TotalMinutes));
}
catch (Exception e)
{
throw e;
}
}
} public override void InitializeRequest(HttpContext context)
{
// Was going to open the redis connection here but sometimes I had 5 connections open at one time which was strange
} public override void EndRequest(HttpContext context)
{
this.Dispose();
}
#endregion Overrides #region Serialization
/// <summary>
/// Serialize is called by the SetAndReleaseItemExclusive method to
/// convert the SessionStateItemCollection into a Base64 string to
/// be stored in MongoDB.
/// </summary>
private string Serialize(SessionStateItemCollection items)
{
using (MemoryStream ms = new MemoryStream())
using (BinaryWriter writer = new BinaryWriter(ms))
{
if (items != null)
items.Serialize(writer); writer.Close(); return Convert.ToBase64String(ms.ToArray());
}
} private SessionStateStoreData Deserialize(HttpContext context, string serializedItems, int timeout)
{
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(serializedItems)))
{
SessionStateItemCollection sessionItems = new SessionStateItemCollection(); if (ms.Length > )
{
using (BinaryReader reader = new BinaryReader(ms))
{
sessionItems = SessionStateItemCollection.Deserialize(reader);
}
} return new SessionStateStoreData(sessionItems,
SessionStateUtility.GetSessionStaticObjects(context),
timeout);
}
}
#endregion Serialization
}
}
<system.web
<sessionState timeout="" mode="Custom" customProvider="RedisSessionStateProvider" cookieless="false">
<providers>
<add name="RedisSessionStateProvider" writeexceptionstoeventlog="false" type="RedisProvider.SessionProvider.CustomServiceProvider" server="192.168.1.118" port="" password="admin"></add>
</providers>
</sessionState>
</system.web>
Redis提供商配置ASP.NET会话状态的更多相关文章
- ASP.NET 会话状态的模式
ASP.NET 会话状态为会话数据提供了几个不同的存储选项.每个选项都通过一个 SessionStateMode 枚举值进行识别.如下列表中描述了可用的会话状态模式: InProc 模式:把会话状态存 ...
- Azure Redis 缓存的 ASP.NET 会话状态提供程序
Azure Redis Cache 提供了一个会话状态提供程序,你可以使用其在缓存中(而不是内存中或在 SQL Server 数据库中)存储会话状态.要使用缓存会话状态提供程序,先首先配置缓存,然后使 ...
- centos 安装php-fpm , nginx二级域名配置 ,但为什么必须要 域名提供商 哪里解析新的二级域名一下 才能用呢?
yum -y install php-fpm php-mysql(当然还有其它扩展) /etc/init.d/php-fpm restart (重启php-fpm) /etc/php.ini (php ...
- 第22章 使用外部身份提供商登录 - Identity Server 4 中文文档(v1.0.0)
ASP.NET Core有一种灵活的方式来处理外部身份验证.这涉及几个步骤. 注意 如果您使用的是ASP.NET Identity,则会隐藏许多基础技术细节.建议您还阅读Microsoft 文档并执行 ...
- Cloud Native Weekly | 华为云抢先发布Redis5.0,红帽宣布收购混合云提供商 NooBaa
1——华为云抢先发布Redis5.0 2——DigitalOcean K8s服务正式上线 3——红帽宣布收购混合云提供商 NooBaa 4——微软发布多项 Azure Kubernetes 服务更新 ...
- 在Linux(Ubuntu/openSUSE/CentOS)下配置ASP.NET(Apache + Mono)
[题外话] 闲的无聊竟然想尝试测试自己做的项目在不同操作系统上的性能表现,所以决定试试在Linux上部署Apache和Mono的环境.由于平时很少接触Linux,所以从网上找了几篇文章(附在相关链接中 ...
- redis的安装配置
主要讲下redis的安装配置,以及以服务的方式启动redis 1.下载最新版本的redis-3.0.7 到http://redis.io/download中下载最新版的redis-3.0.7 下载后 ...
- 用"hosting.json"配置ASP.NET Core站点的Hosting环境
通常我们在 Prgram.cs 中使用硬编码的方式配置 ASP.NET Core 站点的 Hosting 环境,最常用的就是 .UseUrls() . public class Program { p ...
- redis的主从复制配置
redis的主从复制配置 一. 原理 Redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架 ...
随机推荐
- 【PKUSC 2015】的一道数学题
有9个人,每三个人中至少有两个互相认识,求证这里面至少有4个人互相认识 PKU官方题解: 引理:二染色K6中一定有同色K3. 证明:考虑某一个点,它一定连出至少三条同色边(不妨设为红边),这三条边连的 ...
- [BZOJ5462][APIO2018]新家(线段树+堆)
其实这个题第一反应一定是线段树分治,但是这样反而更难考虑了(实际上是可做的但很难想到),可见即使看上去最贴切的算法也未必能有效果. 考虑这个DS题,没有什么模型的转化,可能用到的无非就是线段树.平衡树 ...
- SD 一轮集训 day1 carcar
可以发现每条边只能选一次或者两次,并且最后每个点的度数(∑邻接边选的次数和)都是偶数(代表有欧拉回路). 然后根据题意列一个 n 行 m+1 列的01矩阵,每一行代表一个异或方程组(每个点的度数是偶数 ...
- 【点分治】【哈希表】bzoj2599 [IOI2011]Race
给nlog2n随便过的跪了,不得已弄了个哈希表伪装成nlogn(当然随便卡,好孩子不要学)…… 不过为啥哈希表的大小开小点就RE啊……?必须得超过数据范围一大截才行……谜 #include<cs ...
- 【计算几何】bzoj2338 [HNOI2011]数矩形
对于两条线段,若其中点重合,且长度相等,那么它们一定是某个矩形的对角线. N*N地处理出所有线段,排序,对每一部分中点重合.长度相等的线段进行暴力枚举,更新答案. 用 long double 注意EP ...
- pythonGUI菜单栏和弹出菜单
菜单栏代码: from tkinter import * root = Tk() menubar = Menu(root) def callback(): pass filemenu = Menu(m ...
- python的turtle模块画折线图
代码如下: import turtle yValues = [10.0,7.4,6.4,5.3,4.4,3.7,2.6] def main(): t = turtle.Turtle() t.hidet ...
- 解决ThinkPHP3.2.3框架,PDO驱动类“抛出异常”不起作用的bug
项目中引进了ThinkPHP3.2.3的模型层,发现当SQL语句出错时,系统抛出的异常不是我想要的效果,打开文件 ThinkPHP\Library\Think\Db\Driver.class.php, ...
- 英雄pk理解面向对象中的this指针概念
class Hero { public int ATN { get; set; } public int DEF { get; set; } public int HP { get; set; } p ...
- 【mybatis】mybatis使用java实体中定义的常量,或静态方法
mybatis使用java实体中定义的常量 示例代码: <select id="findDealerInfo" parameterType="com.pisen.c ...