利用HttpHandler和Cache统计点击量
因为访问量大,做页面浏览量的时候不能直接操作库;用文件来记录的话,虽然减缓了数据库的压力但是对服务器I/O却是一个考验;而缓存正是.Net的一大优势,所以想出HttpHandler结合Cache来减缓I/O操作,这样I/O跟数据库的压力都解决了!
首先创建统计类库
1.创建CounterHelper统计类
2.创建HttpHandler
生成dll后创建一个Website,然后把dll引用进来!
接着在web.config里面添加配置:
<httpHandlers>
<add verb="*" path="count.aspx" type="MYSpace.Counter.CounterHandler,MYSpace.Counter" />
</httpHandlers>
最后在web页面调用就ok了。页面代码如下:
首先创建统计类库
1.创建CounterHelper统计类
1
using System;
2
using System.Web;
3
using System.Web.Caching;
4
using System.Collections.Specialized;
5
using System.Data;
6
using System.Data.SqlClient;
7
using System.Configuration;
8
using System.Text;
9
using System.IO;
10![]()
11
namespace MYSpace.Counter
12
{
13
/// <summary>
14
/// Counter 的摘要说明。
15
/// </summary>
16
public class CounterHelper
17
{
18
private int _Hits = 0; //累计的点击数
19
private string _FileName = "";
20
private string FilePth = string.Empty;
21
private string ErrorLogFilePth = string.Empty;
22
private int[] HitsArr = {-1,0,0}; //HitsArr[0]表示总的点击数HitsArr标识昨天的点击数HitsArr表示今天的点击数
23
CacheItemRemovedCallback onRemove = null;//CacheItemRemovedCallback对象
24
private string CacheName = "UpdateHitsForExpired";//缓存名称
25
private object LockForAddHits = new object();//LockForAddHits锁
26
private object LockForItemRemovedFromCacheHits = new object();//ItemRemovedFromCacheHits锁
27![]()
28
/// <summary>
29
/// 构造函数
30
/// </summary>
31
public CounterHelper(string filename)
32
{
33
_FileName = filename;
34
CacheName = filename;
35
HttpContext ctx = HttpContext.Current;
36
FilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");
37
ErrorLogFilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");
38
LoadHits();
39
}
40![]()
41
/// <summary>
42
/// 将累计点击数保存到全局变量,当它达到一定量时保存到文本文件,并清空
43
/// </summary>
44
public void AddHits()
45
{
46
lock(LockForAddHits)
47
{
48
if( Hits != 0 )
49
{
50
Add();
51
if(Hits > 200 )
52
{
53
//--移除
54
HttpRuntime.Cache.Remove(CacheName);
55
}
56
}
57
else
58
{
59
onRemove = new CacheItemRemovedCallback(ItemRemovedFromCache);
60
HttpRuntime.Cache.Insert(
61
CacheName,
62
"This Object For Expired",
63
null,
64
DateTime.Now.AddSeconds(5) ,
65
TimeSpan.Zero,
66
System.Web.Caching.CacheItemPriority.Normal,
67
onRemove
68
);
69
Add();
70
}
71
}
72
}
73![]()
74
/// <summary>
75
/// 保存到文本文件
76
/// </summary>
77
/// <param name="AllId"></param>
78
private void SaveHitsToFile(int hits)
79
{
80
string hitsinfo = string.Empty;
81![]()
82
DateTime LastWriteTime = File.GetLastWriteTime(FilePth);
83
if((DateTime.Today - LastWriteTime).TotalDays >0 )
84
{
85
//--表示今天第一次写数据
86
HitsArr[1] = HitsArr[2];//--将当前累计的点击数赋给昨天的点击数
87
HitsArr[2] = hits;//--设置今天的点击数
88
using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )
89
{
90
streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1] ,hits));
91
streamWriter.Flush();
92
}
93
}
94
else
95
{
96
using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )
97
{
98
streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1],HitsArr[2] + hits));
99
streamWriter.Flush();
100
}
101
}
102
}
103
104
/// <summary>
105
/// 当缓存被移除或过期是触发的回调事件
106
/// </summary>
107
/// <param name="key"></param>
108
/// <param name="value"></param>
109
/// <param name="reason"></param>
110
private void ItemRemovedFromCache(string key, object value,CacheItemRemovedReason reason)
111
{
112
try
113
{
114
清空并写到文本文件
132
}
133
catch(Exception ex)
134
{
135
using(StreamWriter streamWriter = new StreamWriter(ErrorLogFilePth,false) )
136
{
137
streamWriter.Write(string.Format("时间:{0}\r\n描述信息:{1}\r\n",DateTime.Now,ex.Message));
138
streamWriter.Flush();
139
}
140
}
141
}
142![]()
143
/// <summary>
144
/// 获取所有的点击数
145
/// </summary>
146
public int AllHits
147
{
148
get
149
{
150
return HitsArr[0] + Hits;
151
}
152
}
153![]()
154
/// <summary>
155
/// 获取昨天点击数
156
/// </summary>
157
public int YesterdayHits
158
{
159
get
160
{
161
return HitsArr[1];
162
}
163
}
164![]()
165
/// <summary>
166
/// 获取今天点击数
167
/// </summary>
168
public int TodayHits
169
{
170
get
171
{
172
return HitsArr[2] + Hits;
173
}
174
}
175![]()
176
/// <summary>
177
/// 加载点击数
178
/// </summary>
179
private void LoadHits()
180
{
181
if (HttpRuntime.Cache[CacheName] == null)
182
{
183
HttpContext ctx = HttpContext.Current;
184
if (!File.Exists(FilePth))
185
{
186
//--第一次使用
187
using (StreamWriter streamWriter = new StreamWriter(FilePth))
188
{
189
streamWriter.Write(string.Format("{0},{1},{2}", 0, 0, 0));
190
streamWriter.Flush();
191
}
192
HitsArr[0] = 0;
193
HitsArr[1] = 0;
194
HitsArr[2] = 0;
195
}
196
else
197
{
198
string hitsinfo = string.Empty;
199
using (StreamReader objStreamReader = new StreamReader(FilePth))
200
{
201
hitsinfo = objStreamReader.ReadLine();
202
}
203
if (hitsinfo != "")
204
{
205
string[] arr = hitsinfo.Split(',');
206
HitsArr[0] = Convert.ToInt32(arr[0]);//全部
207
HitsArr[1] = Convert.ToInt32(arr[1]);//昨天
208
HitsArr[2] = Convert.ToInt32(arr[2]);//今天
209
}
210
else
211
{
212
HitsArr[0] = 0;
213
HitsArr[1] = 0;
214
HitsArr[2] = 0;
215
}
216
}
217
HttpRuntime.Cache["b" + CacheName] = HitsArr;
218
}
219
else
220
{
221
HitsArr = (int[])HttpRuntime.Cache["b" + CacheName];
222
//HitsArr[0] += 1;
223
//HitsArr[2] += 1;
224![]()
225
}
226
}
227![]()
228![]()
229
/// <summary>
230
/// 获取累计的点击数
231
/// </summary>
232
private int Hits
233
{
234
get
235
{
236
return _Hits;
237
}
238
set
239
{
240
_Hits = value;
241
}
242
}
243![]()
244
/// <summary>
245
/// 累加
246
/// </summary>
247
/// <param name="id"></param>
248
private void Add()
249
{
250
if(HitsArr[2]<14000)
251
{
252
//_Hits = _Hits + new Random(DateTime.Now.Second).Next(60,80);
253
_Hits = _Hits + 1;
254
}
255
else
256
{
257
_Hits = _Hits + 1;//_Hits = _Hits + new Random(DateTime.Now.Second).Next(2,8); 传回指定范围的随机数
258
}
259
}
260
/// <summary>
261
/// 文件名
262
/// </summary>
263
264
/// <summary>
265
/// 获取文件名
266
/// </summary>
267
public string FileName
268
{
269
get { return _FileName; }
270
set { _FileName = value; }
271
}
272
}
273
}
274![]()
using System;2
using System.Web;3
using System.Web.Caching;4
using System.Collections.Specialized;5
using System.Data;6
using System.Data.SqlClient;7
using System.Configuration;8
using System.Text;9
using System.IO;10

11
namespace MYSpace.Counter12
{13
/// <summary>14
/// Counter 的摘要说明。15
/// </summary>16
public class CounterHelper17
{18
private int _Hits = 0; //累计的点击数19
private string _FileName = "";20
private string FilePth = string.Empty;21
private string ErrorLogFilePth = string.Empty;22
private int[] HitsArr = {-1,0,0}; //HitsArr[0]表示总的点击数HitsArr标识昨天的点击数HitsArr表示今天的点击数23
CacheItemRemovedCallback onRemove = null;//CacheItemRemovedCallback对象24
private string CacheName = "UpdateHitsForExpired";//缓存名称25
private object LockForAddHits = new object();//LockForAddHits锁26
private object LockForItemRemovedFromCacheHits = new object();//ItemRemovedFromCacheHits锁27

28
/// <summary>29
/// 构造函数30
/// </summary>31
public CounterHelper(string filename)32
{33
_FileName = filename;34
CacheName = filename;35
HttpContext ctx = HttpContext.Current;36
FilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");37
ErrorLogFilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");38
LoadHits();39
}40

41
/// <summary>42
/// 将累计点击数保存到全局变量,当它达到一定量时保存到文本文件,并清空43
/// </summary>44
public void AddHits()45
{46
lock(LockForAddHits)47
{48
if( Hits != 0 )49
{50
Add();51
if(Hits > 200 )52
{53
//--移除 54
HttpRuntime.Cache.Remove(CacheName);55
}56
}57
else58
{59
onRemove = new CacheItemRemovedCallback(ItemRemovedFromCache);60
HttpRuntime.Cache.Insert(61
CacheName,62
"This Object For Expired", 63
null,64
DateTime.Now.AddSeconds(5) ,65
TimeSpan.Zero,66
System.Web.Caching.CacheItemPriority.Normal,67
onRemove68
);69
Add(); 70
}71
}72
} 73

74
/// <summary>75
/// 保存到文本文件76
/// </summary>77
/// <param name="AllId"></param>78
private void SaveHitsToFile(int hits)79
{80
string hitsinfo = string.Empty; 81

82
DateTime LastWriteTime = File.GetLastWriteTime(FilePth);83
if((DateTime.Today - LastWriteTime).TotalDays >0 )84
{85
//--表示今天第一次写数据86
HitsArr[1] = HitsArr[2];//--将当前累计的点击数赋给昨天的点击数87
HitsArr[2] = hits;//--设置今天的点击数88
using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )89
{90
streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1] ,hits));91
streamWriter.Flush();92
}93
}94
else95
{96
using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )97
{98
streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1],HitsArr[2] + hits));99
streamWriter.Flush();100
}101
}102
} 103
104
/// <summary>105
/// 当缓存被移除或过期是触发的回调事件106
/// </summary>107
/// <param name="key"></param>108
/// <param name="value"></param>109
/// <param name="reason"></param>110
private void ItemRemovedFromCache(string key, object value,CacheItemRemovedReason reason)111
{112
try113
{114
清空并写到文本文件132
}133
catch(Exception ex)134
{135
using(StreamWriter streamWriter = new StreamWriter(ErrorLogFilePth,false) )136
{137
streamWriter.Write(string.Format("时间:{0}\r\n描述信息:{1}\r\n",DateTime.Now,ex.Message));138
streamWriter.Flush();139
}140
}141
}142

143
/// <summary>144
/// 获取所有的点击数145
/// </summary>146
public int AllHits147
{148
get149
{150
return HitsArr[0] + Hits;151
}152
}153

154
/// <summary>155
/// 获取昨天点击数156
/// </summary>157
public int YesterdayHits158
{159
get160
{161
return HitsArr[1];162
}163
} 164

165
/// <summary>166
/// 获取今天点击数167
/// </summary>168
public int TodayHits169
{170
get171
{172
return HitsArr[2] + Hits;173
}174
}175

176
/// <summary>177
/// 加载点击数178
/// </summary>179
private void LoadHits()180
{181
if (HttpRuntime.Cache[CacheName] == null)182
{183
HttpContext ctx = HttpContext.Current;184
if (!File.Exists(FilePth))185
{186
//--第一次使用187
using (StreamWriter streamWriter = new StreamWriter(FilePth))188
{189
streamWriter.Write(string.Format("{0},{1},{2}", 0, 0, 0));190
streamWriter.Flush();191
}192
HitsArr[0] = 0;193
HitsArr[1] = 0;194
HitsArr[2] = 0;195
}196
else197
{198
string hitsinfo = string.Empty;199
using (StreamReader objStreamReader = new StreamReader(FilePth))200
{201
hitsinfo = objStreamReader.ReadLine();202
}203
if (hitsinfo != "")204
{205
string[] arr = hitsinfo.Split(',');206
HitsArr[0] = Convert.ToInt32(arr[0]);//全部207
HitsArr[1] = Convert.ToInt32(arr[1]);//昨天208
HitsArr[2] = Convert.ToInt32(arr[2]);//今天209
}210
else211
{212
HitsArr[0] = 0;213
HitsArr[1] = 0;214
HitsArr[2] = 0;215
}216
}217
HttpRuntime.Cache["b" + CacheName] = HitsArr;218
}219
else220
{221
HitsArr = (int[])HttpRuntime.Cache["b" + CacheName];222
//HitsArr[0] += 1;223
//HitsArr[2] += 1;224

225
}226
}227

228

229
/// <summary>230
/// 获取累计的点击数231
/// </summary>232
private int Hits233
{234
get235
{236
return _Hits;237
}238
set239
{240
_Hits = value;241
}242
}243

244
/// <summary>245
/// 累加246
/// </summary>247
/// <param name="id"></param>248
private void Add()249
{250
if(HitsArr[2]<14000)251
{252
//_Hits = _Hits + new Random(DateTime.Now.Second).Next(60,80);253
_Hits = _Hits + 1;254
}255
else256
{257
_Hits = _Hits + 1;//_Hits = _Hits + new Random(DateTime.Now.Second).Next(2,8); 传回指定范围的随机数258
}259
}260
/// <summary>261
/// 文件名262
/// </summary>263
264
/// <summary>265
/// 获取文件名266
/// </summary>267
public string FileName268
{269
get { return _FileName; }270
set { _FileName = value; }271
}272
}273
}274

2.创建HttpHandler
1
using System;
2
using System.Web;
3
using System.Text.RegularExpressions;
4![]()
5
namespace MYSpace.Counter
6
{
7
/// <summary>
8
/// HitsHandler 的摘要说明。
9
/// </summary>
10
public class CounterHandler: IHttpHandler
11
{
12
public void ProcessRequest(HttpContext ctx)
13
{
14
CounterHelper objCounterHelper = new CounterHelper(ctx.Request.QueryString["id"].ToString());
15
objCounterHelper.AddHits();
16
ctx.Response.Write(string.Format("document.write('页面访问量:{0} 昨日:{1} 今日:{2} id :{3}')",objCounterHelper.AllHits,objCounterHelper.YesterdayHits,objCounterHelper.TodayHits,ctx.Request.Url.AbsoluteUri));
17
}
18![]()
19
public bool IsReusable
20
{
21
get { return false; }
22
}
23
}
24
}
25![]()
using System;2
using System.Web;3
using System.Text.RegularExpressions;4

5
namespace MYSpace.Counter6
{7
/// <summary>8
/// HitsHandler 的摘要说明。9
/// </summary>10
public class CounterHandler: IHttpHandler11
{12
public void ProcessRequest(HttpContext ctx) 13
{14
CounterHelper objCounterHelper = new CounterHelper(ctx.Request.QueryString["id"].ToString());15
objCounterHelper.AddHits();16
ctx.Response.Write(string.Format("document.write('页面访问量:{0} 昨日:{1} 今日:{2} id :{3}')",objCounterHelper.AllHits,objCounterHelper.YesterdayHits,objCounterHelper.TodayHits,ctx.Request.Url.AbsoluteUri));17
}18

19
public bool IsReusable 20
{21
get { return false; } 22
}23
}24
}25

生成dll后创建一个Website,然后把dll引用进来!
接着在web.config里面添加配置:
<httpHandlers>
<add verb="*" path="count.aspx" type="MYSpace.Counter.CounterHandler,MYSpace.Counter" />
</httpHandlers>
最后在web页面调用就ok了。页面代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
<SCRIPT LANGUAGE="JavaScript" src='count.aspx?id=o4'></SCRIPT>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
很简单吧,这里只介绍到写入文件,如果想写入库里面,直接读取文件里的数值就搞定!



浙公网安备 33010602011771号