码迷,mamicode.com
首页 > 其他好文 > 详细

session存入Couchbase实现多服务器共享

时间:2019-10-02 12:25:33      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:rtu   ring   addm   信息   catch   初始化   sub   serial   override   

新建CouchBaseSessionProvider类,继承SessionStateStoreProviderBase类。

public sealed class CouchBaseSessionStateStore : SessionStateStoreProviderBase
{
private SessionStateSection pConfig = null;
private string eventSource = "CouchBaseSessionStateStore";
private string eventLog = "Application";
private string pApplicationName;


private bool pWriteExceptionsToEventLog = false;
public bool WriteExceptionsToEventLog
{
get { return pWriteExceptionsToEventLog; }
set { pWriteExceptionsToEventLog = value; }
}
/// <summary>
/// 用于不同请求的Session名称
/// </summary>
public string ApplicationName
{
get { return pApplicationName; }
}

public override void Initialize(string name, NameValueCollection config)
{
if (config == null)
NLogger.Instance.WriteLog(NLogger.LogLevel.Info, string.Format("Session_Initialize_ex:{0}", new ArgumentNullException("config")));
//throw new ArgumentNullException("config");
if (name == null || name.Length == 0)
name = "CouchBaseSessionStateStore";
if (String.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "Sample CouchBase Session State Store provider");
}

base.Initialize(name, config);
pApplicationName = HostingEnvironment.ApplicationVirtualPath;
Configuration cfg = WebConfigurationManager.OpenWebConfiguration(ApplicationName);
//获取配置文件中的<sessionstate>的节点
pConfig = (SessionStateSection)cfg.GetSection("system.web/sessionState");

//写异常的初始化
pWriteExceptionsToEventLog = false;
if (config["writeExceptionToEventLog"] != null)
{
if (config["writeExceptionToEventLog"].ToUpper() == "TRUE")
pWriteExceptionsToEventLog = true;
}
}

public override void Dispose()
{
}
public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
{
return false;
}

public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
{
string sessItems = Serialize((SessionStateItemCollection)item.Items);

try
{
var result = CouchBase.Session_bucket.Get<CouchBaseSession>(string.Format("Session_{0}", id));
var session = result.Value;
if (newItem)
{
//先删除已存在的项再插入最新的 DELETE FROM Sessions WHERE SessionId = ? AND ApplicationName = ? AND Expires < ?" INSERT INTO Sessions (SessionId, ApplicationName, Created, Expires, LockDate, LockId, Timeout, Locked, SessionItems, Flags)"
if (result.Success)
{
if (session.SessionId == id && session.ApplicationName == ApplicationName && session.Expires < DateTime.Now)
{
CouchBase.DeleteSession(session.GetCbKey());
}
}
CouchBase.SessionInsert(string.Format("Session_{0}", id), new CouchBaseSession { ApplicationName = ApplicationName, SessionId = id, Created = DateTime.Now, Expires = DateTime.Now.AddMinutes(pConfig.Timeout.TotalMinutes), LockDate = DateTime.Now, LockId = 0, Locked = false, SessionItems = sessItems, Flags = 0 }, pConfig.Timeout);
}
else
{
//更新以前的项目"UPDATE Sessions SET Expires = ?, SessionItems = ?, Locked = ? WHERE SessionId = ? AND ApplicationName = ? AND LockId = ?"
if (result.Success)
{
session.SessionId = id;
session.Expires = DateTime.Now.AddMinutes(pConfig.Timeout.TotalMinutes);
session.Locked = false;
session.SessionItems = sessItems;
session.Flags = 0;
session.Timeout = (int)pConfig.Timeout.TotalMinutes;

CouchBase.SessionInsert(session.GetCbKey(), session, pConfig.Timeout);
}
}
}
catch (Exception ex)
{
NLogger.Instance.WriteLog(NLogger.LogLevel.Info, string.Format("Session_SetAndReleaseItemExclusive_ex:{0}", ex.ToString()));
}
}

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);
}
public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
{
return GetSessionStoreItem(true, 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)
{
SessionStateStoreData item = null;
lockAge = TimeSpan.Zero;
lockId = 0;
locked = false;
actionFlags = 0;
DateTime expires;
// String to hold serialized SessionStateItemCollection.
string serializedItems = "";
// True if a record is found in the database.
bool foundRecord = false;
// True if the returned session item is expired and needs to be deleted.
bool deleteData = false;
// Timeout value from the data store.
int timeout = 60;
try
{
//1.查询当前session的信息 "SELECT Expires, SessionItems, LockId, LockDate, Flags, Timeout FROM Sessions WHERE SessionId = ? AND ApplicationName = ?"
var getresult = CouchBase.Session_bucket.Get<CouchBaseSession>(string.Format("Session_{0}", id));
var result = getresult.Value;
//如是GetItem的调用则lockRecord为false 如是GetItemExclusive的调用则为true
if (lockRecord)
{
// "UPDATE Sessions SET Locked = ?, LockDate = ? WHERE SessionId = ? AND ApplicationName = ? AND Locked = ? AND Expires > ?"
//如更新结果为true则locked为false 反之为true
if (getresult.Success)
{
serializedItems = result.SessionItems;
lockId = result.LockId;
timeout = result.Timeout;
lockAge = DateTime.Now.Subtract(result.LockDate);
actionFlags = (SessionStateActions)result.Flags;
if (result.Expires >= DateTime.Now && result.Locked == false && result.ApplicationName == ApplicationName)
{
result.SessionId = id;
result.LockDate = DateTime.Now;
result.Locked = true;
result.Flags = 0;
result.Timeout = timeout;
var flag = CouchBase.SessionInsert<CouchBaseSession>(result.GetCbKey(), result, pConfig.Timeout);
if (flag)
locked = false;
else
locked = true;
}
}
}


//2.如查询结果不为空 将查询结果中的值得过期时间与当前时间对比 如是过期 则locked为false deleteData为true 反之 foundRecord为true 并将Session项进行赋值
if (getresult.Success)
{
if (result.Expires < DateTime.Now)
{
locked = false;
deleteData = true;
}
else
foundRecord = true;
}

//若返回的session已过期 则删除对应项"DELETE FROM Sessions WHERE SessionId = ? AND ApplicationName = ?"
if (deleteData)
CouchBase.DeleteSession(string.Format("Session_{0}", id));
if (!foundRecord)
locked = false;
//若查询到满足条件的数据并且保留了锁 则设置lockId 并清除actionFlags 并创建SessionStateStoreItem用于返回
if (foundRecord && !locked)
{
lockId = (int)lockId + 1;
//"UPDATE Sessions SET LockId = ?, Flags = 0 WHERE SessionId = ? AND ApplicationName = ?"
if (actionFlags == SessionStateActions.InitializeItem)
item = CreateNewStoreData(context, timeout);
else
item = Deserialize(context, serializedItems, timeout);
}
}
catch (Exception ex)
{
if (WriteExceptionsToEventLog)
{
WriteToEventLog(ex, "GetSessionStoreItem");
//throw new ProviderException(ex.Message);
}
NLogger.Instance.WriteLog(NLogger.LogLevel.Info, string.Format("Session_GetSessionStoreItem_ex:{0}", ex.ToString()));
}
return item;
}

private void WriteToEventLog(Exception ex, string action)
{
EventLog log = new EventLog();
log.Source = eventSource;
log.Log = eventLog;

string message =
"An exception occurred communicating with the data source.\n\n";
message += "Action: " + action + "\n\n";
message += "Exception: " + ex.ToString();

log.WriteEntry(message);
}

public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
{
try
{
//"UPDATE Sessions SET Locked = 0, Expires = ? WHERE SessionId = ? AND ApplicationName = ? AND LockId = ?"
var getresult = CouchBase.Session_bucket.Get<CouchBaseSession>(string.Format("Session_{0}", id));
var result = getresult.Value;
if (getresult.Success)
{
result.Locked = false;
result.Expires = DateTime.Now.AddMinutes(pConfig.Timeout.TotalMinutes);
result.SessionId = id;
result.ApplicationName = ApplicationName;

CouchBase.SessionInsert(result.GetCbKey(), result, pConfig.Timeout);
}

}
catch (Exception ex)
{
if (WriteExceptionsToEventLog)
{
WriteToEventLog(ex, "ReleaseItemExclusive");
//throw new ProviderException(ex.Message);
}
NLogger.Instance.WriteLog(NLogger.LogLevel.Info, string.Format("Session_ReleaseItemExclusive_ex:{0}", ex.ToString()));

}

}
public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
{
try
{
//INSERT INTO Sessions (SessionId, ApplicationName, Created, Expires, LockDate, LockId, Timeout, Locked, SessionItems, Flags) "
CouchBase.SessionInsert(string.Format("Session_{0}", id), new CouchBaseSession { Locked = false, Expires = DateTime.Now.AddMinutes((Double)timeout), SessionId = id, Flags = 1, ApplicationName = ApplicationName, Created = DateTime.Now, LockDate = DateTime.Now, LockId = 0, SessionItems = "", Timeout = timeout }, pConfig.Timeout);
}
catch (Exception ex)
{
if (WriteExceptionsToEventLog)
{
WriteToEventLog(ex, "CreateUninitializedItem");
//throw new ProviderException(ex.Message);
}
NLogger.Instance.WriteLog(NLogger.LogLevel.Info, string.Format("Session_CreateUninitializedItem_ex:{0}", ex.ToString()));
}
}
public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
{
try
{
//DELETE * FROM Sessions WHERE SessionId = ? AND ApplicationName = ? AND LockId = ?"
CouchBase.DeleteSession(string.Format("Session_{0}", id));
}
catch (Exception ex)
{
if (WriteExceptionsToEventLog)
{
WriteToEventLog(ex, "RemoveItem");
//throw new ProviderException(ex.Message);
}
NLogger.Instance.WriteLog(NLogger.LogLevel.Info, string.Format("Session_RemoveItem_ex:{0}", ex.ToString()));

}
}
public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
{
return new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout);
}
public override void ResetItemTimeout(HttpContext context, string id)
{
try
{
//"UPDATE Sessions SET Expires = ? WHERE SessionId = ? AND ApplicationName = ?"
if (CouchBase.Session_bucket.Exists(string.Format("Session_{0}", id)))
{
CouchBase.Session_bucket.Touch(string.Format("Session_{0}", id), pConfig.Timeout);
}
}
catch (Exception ex)
{
if (WriteExceptionsToEventLog)
{
WriteToEventLog(ex, "ResetItemTimeout");
//throw new ProviderException(ex.Message);
NLogger.Instance.WriteLog(NLogger.LogLevel.Info, string.Format("Session_ResetItemTimeout_ex:{0}", ex.ToString()));
}
}
}

public override void EndRequest(HttpContext context)
{
}
public override void InitializeRequest(HttpContext context)
{
}
private SessionStateStoreData Deserialize(HttpContext context, string serializedItems, int timeout)
{
SessionStateItemCollection SessionItems = new SessionStateItemCollection();
if (!String.IsNullOrWhiteSpace(serializedItems))
{
MemoryStream ms = new MemoryStream(Convert.FromBase64String(serializedItems));
if (ms.Length > 0)
{
BinaryReader reader = new BinaryReader(ms);
SessionItems = SessionStateItemCollection.Deserialize(reader);
}
}
return new SessionStateStoreData(SessionItems, SessionStateUtility.GetSessionStaticObjects(context), timeout);

}

private string Serialize(SessionStateItemCollection items)
{
MemoryStream ms = new MemoryStream();
BinaryWriter writer = new BinaryWriter(ms);
if (items != null)
items.Serialize(writer);
writer.Close();
return Convert.ToBase64String(ms.ToArray());
}
}

 

在web.config的<system.web>中加入:

<sessionState cookieless="false" regenerateExpiredSessionId="false" timeout="60" mode="Custom" customProvider="CouchBaseSessionProvider">
<providers>
<add name="CouchBaseSessionProvider" type="guotaigold.WebSite.Component.Framework.CouchBaseSessionStateStore" writeExceptionsToEventLog="false" />
</providers>
</sessionState>

 

session存入Couchbase实现多服务器共享

标签:rtu   ring   addm   信息   catch   初始化   sub   serial   override   

原文地址:https://www.cnblogs.com/cathyxiao/p/11617123.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!