using System.Collections.Generic;
using System.Net;
using CYQ.Data;
using CYQ.Data.Cache;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;
namespace System.Web
{
///
/// 分布式Session
///
public class HttpSessionState
{
public static readonly HttpSessionState Instance = new HttpSessionState();
protected Microsoft.AspNetCore.Http.HttpContext context
{
get
{
return HttpContext.contextAccessor.HttpContext;
}
}
internal HttpSessionState()
{
Timeout = 20;
}
///
/// 超时时间,默认20分钟
///
public int Timeout { get; set; }
List keys = new List();
DistributedCache cache = DistributedCache.Local;
public string SessionID
{
get
{
if (context.Items.ContainsKey("HttpSessionID"))
{
return context.Items["HttpSessionID"] as String;
}
string sessionID = context.Request.Cookies["CYQ.SessionID"];
if (string.IsNullOrEmpty(sessionID))
{
if (context.Request.Cookies.Count == 0)
{
string referer = context.Request.Headers["Referer"];
if (string.IsNullOrEmpty(referer))
{
return string.Empty;//API请求,不产生Cookie。
}
}
sessionID = DateTime.Now.ToString("HHmmss") + Guid.NewGuid().GetHashCode();
if(context.Request.IsHttps)
{
context.Response.Cookies.Append("CYQ.SessionID", sessionID, new CookieOptions() { SameSite = SameSiteMode.None, Secure = true });
}
else
{
context.Response.Cookies.Append("CYQ.SessionID", sessionID);
}
}
context.Items.Add("HttpSessionID", sessionID);
return sessionID;
}
}
private string GetName(string name)
{
return name + "_" + SessionID;
}
public object this[int index]
{
get
{
if (index < keys.Count)
{
return this[keys[index]];
}
return null;
}
set
{
if (index < keys.Count)
{
this[keys[index]] = value;
}
}
}
public object this[string name]
{
get
{
string key = GetName(name);
object obj = cache.Get(key);
if (obj != null && DateTime.Now.Second % 9 == 0)
{
cache.Set(key, obj, Timeout);//用随机概率延长时间
}
return obj;
}
set
{
Add(name, value);
}
}
public void Add(string name, object value)
{
cache.Set(GetName(name), value, Timeout);
if (keys.Contains(name))
{
keys.Add(name);
}
}
public void Remove(string key)
{
cache.Remove(GetName(key));
}
public bool IsAvailable => true;
public IEnumerable Keys
{
get
{
return keys;
}
}
///
/// 清空当前会话的所有数据。
///
public void Clear()
{
foreach (string key in keys)
{
Remove(key);
}
}
}
}