145 lines
4.0 KiB
C#
145 lines
4.0 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 分布式Session
|
||
/// </summary>
|
||
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;
|
||
}
|
||
/// <summary>
|
||
/// 超时时间,默认20分钟
|
||
/// </summary>
|
||
public int Timeout { get; set; }
|
||
List<string> keys = new List<string>();
|
||
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<string> Keys
|
||
{
|
||
get
|
||
{
|
||
return keys;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清空当前会话的所有数据。
|
||
/// </summary>
|
||
public void Clear()
|
||
{
|
||
foreach (string key in keys)
|
||
{
|
||
Remove(key);
|
||
}
|
||
}
|
||
}
|
||
} |