利用Application对象和Session对象可以统计历史访问人数和当前在线人数。
在会话开始和结束时,一定要进行加锁和解锁操作。由于多个用户可以共享Application对象,因此加锁是必要的,这样可以保证在同一时刻只有一个客户可以修改和存取Application对象的属性。如果加锁后,迟迟不给开锁,会导致用户无法访问Application对象。我们可以使用对象的Unlock方法来解除锁定。
在项目的web层的根目录下新建全局配置文件Global.asax以及日志文件VisitedLog.txt,这样做的好处是不用操作数据库,将计数写入日志文件,即使服务器重启计数也不会清零。首先,在Global.asax文件中添加以下代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Security; 6 using System.Web.SessionState; 7 8 namespace xxjy.Global 9 { 10 public class Global : System.Web.HttpApplication 11 { 12 string sLogFile = AppDomain.CurrentDomain.BaseDirectory + "VisitedLog.txt";//日志文件的路径 13 protected void Application_Start(object sender, EventArgs e) 14 { 15 // 在应用程序启动时运行的代码 16 // Code that runs on application startup 17 //刚启动,为了防止服务器意外死机重启等因素,需要从记录文件中读取数目 18 if (!System.IO.File.Exists(sLogFile)) 19 { 20 System.IO.FileStream fsnew = System.IO.File.Create(sLogFile); 21 fsnew.Close(); 22 } 23 string[] lines = System.IO.File.ReadAllLines(sLogFile);//读取并得到日志文件的行数 24 double iTotalCount = 0;//设置初始访问人数为0 25 int iOnline = 0;//设置初始在线人数为0 26 if (lines != null && lines.Length > 0) 27 { 28 Double.TryParse(lines[lines.Length - 1].ToString(), out iTotalCount); 29 } 30 Application["TotalCount"] = iTotalCount; 31 Application["Online"] = iOnline; 32 } 33 34 protected void Session_Start(object sender, EventArgs e) 35 { 36 // 在新会话启动时运行的代码 37 // Code that runs when a new session is started 38 Session.Timeout = 10; 39 Application.Lock();//锁定变量 40 Application["TotalCount"] = System.Convert.ToDouble(Application["TotalCount"]) + 1;//为页面访问量+1 41 Application["Online"] = System.Convert.ToInt32(Application["Online"]) + 1;//为页面在线人数+1 42 Application.UnLock();//解锁 43 if (Convert.ToInt32(Application["TotalCount"]) % 50 == 0) //为了防止服务器死机重启等意外因素丢失数据,我们每隔50个访客更新一下记录文件,这个需要根据访问量调整 44 { 45 System.IO.StreamWriter rw = System.IO.File.CreateText(sLogFile); 46 rw.WriteLine(Application["TotalCount"]); 47 rw.Flush(); 48 rw.Close(); 49 } 50 } 51 52 protected void Application_BeginRequest(object sender, EventArgs e) 53 { 54 55 } 56 57 protected void Application_AuthenticateRequest(object sender, EventArgs e) 58 { 59 60 } 61 62 protected void Application_Error(object sender, EventArgs e) 63 { 64 // 在出现未处理的错误时运行的代码 65 } 66 67 protected void Session_End(object sender, EventArgs e) 68 { 69 // 在会话结束时运行的代码。 70 // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为 71 // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer 72 // 或 SQLServer,则不会引发该事件。 73 Application.Lock(); 74 Application["Online"] = System.Convert.ToInt32(Application["Online"]) - 1;//在线人数减1 75 Application.UnLock(); 76 77 } 78 79 protected void Application_End(object sender, EventArgs e) 80 { 81 //在应用程序关闭时运行的代码 82 //保存当前访问 83 System.IO.StreamWriter rw = System.IO.File.CreateText(sLogFile); 84 rw.WriteLine(Application["TotalCount"]); 85 rw.Flush(); 86 rw.Close(); 87 } 88 } 89 }
然后在xxx.aspx页面添加能显示文本的控件,如label,或直接在cs文件中用Rsponse.write()输出。
接着在cs中添加如下代码:
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 if (!IsPostBack) 4 { 5 if (Application["TotalCount"] != null) 6 { 7 Label1.Text = Application["TotalCount"].ToString(); 8 } 9 } 10 }