接一的考虑,那么就做Redis的SessionProvider就非常简单了,只考虑整个Session的缓存,主要实现以下两个函数就可以了
public override SessionStateStoreData GetItem(System.Web.HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
OpenRedis();
var response = _connection.Strings.Get(_dbNumber, id);
var value = _connection.Wait(response);
var sessionItems = value.FromBinary<SerializableSessionStateItemCollection>(); locked = false;
lockAge = new TimeSpan();
lockId = null;
actions = SessionStateActions.None; SessionStateStoreData storeData = null;
if (sessionItems != null)
{
storeData = new SessionStateStoreData(sessionItems, SessionStateUtility.GetSessionStaticObjects(context), _timeout);
}
else
{
storeData = new SessionStateStoreData(new SerializableSessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), _timeout);
}
return storeData;
} public override SessionStateStoreData GetItemExclusive(System.Web.HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
return GetItem(context, id, out locked, out lockAge, out lockId, out actions);
}
public override void SetAndReleaseItemExclusive(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
{
OpenRedis();
var items = item.Items as SerializableSessionStateItemCollection;
if (items != null)
{
var response = _connection.Strings.Set(_dbNumber, id, item.Items.ToBinary(), _timeout*);
_connection.Wait(response);
}
}
配置Web.Config
<sessionState mode="Custom" customProvider="redis" timeout="20">
<providers>
<add name="redis" type=".Web.Session.RedisSessionProvider,Common.Web" server="localhost" port ="6379" dbNumber="2"/>
</providers>
</sessionState>
调试通过,包括设置和获取Session,Session超时,Session Aband,基本达到要求,美中不足的是,存入Session的对象必须标记可序列化的。
经测试发现,每次Request,都会调用上面的2个函数,用户量大的时候,redis会有点压力