验证URL中GUID值是否重复的类库,防止用户直截刷URL(代码存在问题,一直没找到来。看有没有高人能看出来。)
验证URL中GUID值是否重复的类库,防止用户直截刷URL,设计思路如下:
定义了两个队列:
当前写入队列 Hashtable writeTb
备份队列 Hashtable readTb
已经使用过的GUID值记录在writeTb,readTb列表中。
当新的GUID值上来的时候,判断writeTb,readTb队列中是否存在GUID值,如果存在,就判断为非法。
两个队列根据一定的间隔时间来轮换切读写。当readTb切换成写队列的时候。readTb中记录的GUID值全部清除。
直接上代码:(代码是存在问题的,没跑多久的时候CPU就100%了,一直找不到问题,看看有没有高人能看出问题所在)
View Code
1 public class RequestValidate
2 {
3 private Thread clearTbWorker = null;
4 private Hashtable tb1 = new Hashtable(100000);
5 private Hashtable tb2 = new Hashtable(100000);
6
7 /// <summary>
8 /// 上次转换TB时间
9 /// </summary>
10 private DateTime lastSwitchTbTime { get; set; }
11
12 /// <summary>
13 /// 写TB索引
14 /// </summary>
15 private int writeTbIndex{get;set;}
16
17 /// <summary>
18 /// 当前写入队列
19 /// </summary>
20 private Hashtable writeTb
21 {
22 get
23 {
24 if (writeTbIndex == 1) return tb1;
25 else return tb2;
26 }
27 }
28
29 /// <summary>
30 /// 备份队列
31 /// </summary>
32 private Hashtable readTb
33 {
34 get
35 {
36 if (writeTbIndex == 1) return tb2;
37 else return tb1;
38 }
39 }
40
41 private HttpRequest request { get { return HttpContext.Current.Request; } }
42
43 /// <summary>
44 /// GUID受限使用时间
45 /// </summary>
46 private TimeSpan GuidExpiredMinute = TimeSpan.FromMinutes(2);
47
48 private RequestValidate()
49 {
50 lastSwitchTbTime = System.DateTime.Now;
51 clearTbWorker = new Thread(new ThreadStart(ClearTbWork));
52 clearTbWorker.Start();
53 }
54
55 private static RequestValidate instance = null;
56 public static RequestValidate Instance
57 {
58 get
59 {
60 if (instance == null)
61 {
62 lock (typeof(RequestValidate))
63 {
64 if (instance == null)
65 {
66 instance = new RequestValidate();
67 }
68 }
69 }
70 return instance;
71 }
72 }
73
74 /// <summary>
75 /// 验证客户端GUID值是否合法
76 /// </summary>
77 /// <returns></returns>
78 public bool Validate()
79 {
80 string guid = request["guid"];
81 if (string.IsNullOrEmpty(guid))
82 {
83 #if DEBUG
84 return false;
85 #else
86 return true;
87 #endif
88 }
89
90 if (!string.IsNullOrEmpty(request["t"]))
91 {
92 HttpContext.Current.Response.ContentType = "text/html";
93 HttpContext.Current.Response.Write("readTb:"+readTb.Count);
94 HttpContext.Current.Response.Write("writeTb:" + this.writeTb.Count);
95 HttpContext.Current.Response.End();
96 }
97
98 bool isTrue = true;
99
100 try
101 {
102 string htKey = guid.ToLower();
103 if (readTb.ContainsKey(htKey))
104 {
105 isTrue = false;
106 }
107 else if (writeTb.ContainsKey(htKey))
108 {
109 isTrue = false;
110 }
111 else
112 {
113 writeTb[htKey] = System.DateTime.Now;
114 }
115 }
116 catch (Exception ex)
117 {
118 Log.LogComplement.Error(ex);
119 }
120
121 return isTrue;
122
123 }
124
125 /// <summary>
126 /// 清除过期队列
127 /// </summary>
128 private void ClearTbWork()
129 {
130 while (true)
131 {
132 try
133 {
134
135
136 TimeSpan ts = System.DateTime.Now - lastSwitchTbTime;
137 if (ts < GuidExpiredMinute)
138 {
139 System.Threading.Thread.Sleep(ts);
140 }
141
142 //清除GuidExpiredMinute分钟之前备份队列
143 readTb.Clear();
144
145 if (writeTbIndex == 1) writeTbIndex = 2;
146 else writeTbIndex = 1;
147
148 lastSwitchTbTime = System.DateTime.Now;
149
150
151
152 }
153 catch (Exception ex)
154 {
155 Log.LogComplement.Error(ex);
156 }
157 finally
158 {
159 System.Threading.Thread.Sleep(GuidExpiredMinute);
160 }
161 }
162
163 }
164
165 }
2 {
3 private Thread clearTbWorker = null;
4 private Hashtable tb1 = new Hashtable(100000);
5 private Hashtable tb2 = new Hashtable(100000);
6
7 /// <summary>
8 /// 上次转换TB时间
9 /// </summary>
10 private DateTime lastSwitchTbTime { get; set; }
11
12 /// <summary>
13 /// 写TB索引
14 /// </summary>
15 private int writeTbIndex{get;set;}
16
17 /// <summary>
18 /// 当前写入队列
19 /// </summary>
20 private Hashtable writeTb
21 {
22 get
23 {
24 if (writeTbIndex == 1) return tb1;
25 else return tb2;
26 }
27 }
28
29 /// <summary>
30 /// 备份队列
31 /// </summary>
32 private Hashtable readTb
33 {
34 get
35 {
36 if (writeTbIndex == 1) return tb2;
37 else return tb1;
38 }
39 }
40
41 private HttpRequest request { get { return HttpContext.Current.Request; } }
42
43 /// <summary>
44 /// GUID受限使用时间
45 /// </summary>
46 private TimeSpan GuidExpiredMinute = TimeSpan.FromMinutes(2);
47
48 private RequestValidate()
49 {
50 lastSwitchTbTime = System.DateTime.Now;
51 clearTbWorker = new Thread(new ThreadStart(ClearTbWork));
52 clearTbWorker.Start();
53 }
54
55 private static RequestValidate instance = null;
56 public static RequestValidate Instance
57 {
58 get
59 {
60 if (instance == null)
61 {
62 lock (typeof(RequestValidate))
63 {
64 if (instance == null)
65 {
66 instance = new RequestValidate();
67 }
68 }
69 }
70 return instance;
71 }
72 }
73
74 /// <summary>
75 /// 验证客户端GUID值是否合法
76 /// </summary>
77 /// <returns></returns>
78 public bool Validate()
79 {
80 string guid = request["guid"];
81 if (string.IsNullOrEmpty(guid))
82 {
83 #if DEBUG
84 return false;
85 #else
86 return true;
87 #endif
88 }
89
90 if (!string.IsNullOrEmpty(request["t"]))
91 {
92 HttpContext.Current.Response.ContentType = "text/html";
93 HttpContext.Current.Response.Write("readTb:"+readTb.Count);
94 HttpContext.Current.Response.Write("writeTb:" + this.writeTb.Count);
95 HttpContext.Current.Response.End();
96 }
97
98 bool isTrue = true;
99
100 try
101 {
102 string htKey = guid.ToLower();
103 if (readTb.ContainsKey(htKey))
104 {
105 isTrue = false;
106 }
107 else if (writeTb.ContainsKey(htKey))
108 {
109 isTrue = false;
110 }
111 else
112 {
113 writeTb[htKey] = System.DateTime.Now;
114 }
115 }
116 catch (Exception ex)
117 {
118 Log.LogComplement.Error(ex);
119 }
120
121 return isTrue;
122
123 }
124
125 /// <summary>
126 /// 清除过期队列
127 /// </summary>
128 private void ClearTbWork()
129 {
130 while (true)
131 {
132 try
133 {
134
135
136 TimeSpan ts = System.DateTime.Now - lastSwitchTbTime;
137 if (ts < GuidExpiredMinute)
138 {
139 System.Threading.Thread.Sleep(ts);
140 }
141
142 //清除GuidExpiredMinute分钟之前备份队列
143 readTb.Clear();
144
145 if (writeTbIndex == 1) writeTbIndex = 2;
146 else writeTbIndex = 1;
147
148 lastSwitchTbTime = System.DateTime.Now;
149
150
151
152 }
153 catch (Exception ex)
154 {
155 Log.LogComplement.Error(ex);
156 }
157 finally
158 {
159 System.Threading.Thread.Sleep(GuidExpiredMinute);
160 }
161 }
162
163 }
164
165 }