验证URL中GUID值是否重复的类库,防止用户之截刷URL(代码存在问题,一直没找到来。看有没有高人能看出来。)
验证URL中GUID值是否重复的类库,防止用户直截刷URL,设计思路如下:
定义了两个队列:
当前写入队列 Hashtable writeTb
备份队列 Hashtable readTb
已经使用过的GUID值记录在writeTb,readTb列表中。
当新的GUID值上来的时候,判断writeTb,readTb队列中是否存在GUID值,如果存在,就判断为非法。
两个队列根据一定的间隔时间来轮换切读写。当readTb切换成写队列的时候。readTb中记录的GUID值全部清除。
直接上代码:(代码是存在问题的,没跑多久的时候CPU就100%了,一直找不到问题,看看有没有高人能看出问题所在)
public class RequestValidate
{
private Thread clearTbWorker = null;
private Hashtable tb1 = new Hashtable(100000);
private Hashtable tb2 = new Hashtable(100000);
/// <summary>
/// 上次转换TB时间
/// </summary>
private DateTime lastSwitchTbTime { get; set; }
/// <summary>
/// 写TB索引
/// </summary>
private int writeTbIndex{get;set;}
/// <summary>
/// 当前写入队列
/// </summary>
private Hashtable writeTb
{
get
{
if (writeTbIndex == 1) return tb1;
else return tb2;
}
}
/// <summary>
/// 备份队列
/// </summary>
private Hashtable readTb
{
get
{
if (writeTbIndex == 1) return tb2;
else return tb1;
}
}
private HttpRequest request { get { return HttpContext.Current.Request; } }
/// <summary>
/// GUID受限使用时间
/// </summary>
private TimeSpan GuidExpiredMinute = TimeSpan.FromMinutes(2);
private RequestValidate()
{
lastSwitchTbTime = System.DateTime.Now;
clearTbWorker = new Thread(new ThreadStart(ClearTbWork));
clearTbWorker.Start();
}
private static RequestValidate instance = null;
public static RequestValidate Instance
{
get
{
if (instance == null)
{
lock (typeof(RequestValidate))
{
if (instance == null)
{
instance = new RequestValidate();
}
}
}
return instance;
}
}
/// <summary>
/// 验证客户端GUID值是否合法
/// </summary>
/// <returns></returns>
public bool Validate()
{
string guid = request["guid"];
if (string.IsNullOrEmpty(guid))
{
#if DEBUG
return false;
#else
return true;
#endif
}
if (!string.IsNullOrEmpty(request["t"]))
{
HttpContext.Current.Response.ContentType = "text/html";
HttpContext.Current.Response.Write("readTb:"+readTb.Count);
HttpContext.Current.Response.Write("writeTb:" + this.writeTb.Count);
HttpContext.Current.Response.End();
}
bool isTrue = true;
try
{
string htKey = guid.ToLower();
if (readTb.ContainsKey(htKey))
{
isTrue = false;
}
else if (writeTb.ContainsKey(htKey))
{
isTrue = false;
}
else
{
writeTb[htKey] = System.DateTime.Now;
}
}
catch (Exception ex)
{
Log.LogComplement.Error(ex);
}
return isTrue;
}
/// <summary>
/// 清除过期队列
/// </summary>
private void ClearTbWork()
{
while (true)
{
try
{
TimeSpan ts = System.DateTime.Now - lastSwitchTbTime;
if (ts < GuidExpiredMinute)
{
System.Threading.Thread.Sleep(ts);
}
//清除GuidExpiredMinute分钟之前备份队列
readTb.Clear();
if (writeTbIndex == 1) writeTbIndex = 2;
else writeTbIndex = 1;
lastSwitchTbTime = System.DateTime.Now;
}
catch (Exception ex)
{
Log.LogComplement.Error(ex);
}
finally
{
System.Threading.Thread.Sleep(GuidExpiredMinute);
}
}
}
}