zoukankan      html  css  js  c++  java
  • 利用HttpHandler和Cache统计点击量 {转}

    来源: http://www.cnblogs.com/keepsilence/archive/2009/07/23/1529199.html

       因为访问量大,做页面浏览量的时候不能直接操作库;用文件来记录的话,虽然减缓了数据库的压力但是对服务器I/O却是一个考验;而缓存正是.Net的一大优势,所以想出HttpHandler结合Cache来减缓I/O操作,这样I/O跟数据库的压力都解决了!

    首先创建统计类库

    1.创建CounterHelper统计类

    using System;
    using System.Web;
    using System.Web.Caching;
    using System.Collections.Specialized;
    using System.Data;
    using System.Data.SqlClient;
    using System.Configuration;
    using System.Text;
    using System.IO;

    namespace MYSpace.Counter

    {
    /// <summary>
    /// Counter 的摘要说明。
    /// </summary>
        public class CounterHelper
        {
           private  int _Hits = 0; //累计的点击数
           private string _FileName = "";
           private string FilePth = string.Empty;
           private string ErrorLogFilePth = string.Empty;
           private   int[] HitsArr = {-1,0,0}; //HitsArr[0]表示总的点击数HitsArr标识昨天的点击数HitsArr表示今天的点击数
           CacheItemRemovedCallback onRemove = null;//CacheItemRemovedCallback对象
           private  string CacheName = "UpdateHitsForExpired";//缓存名称
           private object LockForAddHits = new object();//LockForAddHits锁
           private object LockForItemRemovedFromCacheHits = new object();//ItemRemovedFromCacheHits        锁

           /**//// <summary>
           /// 构造函数
           /// </summary>
           public CounterHelper(string filename)
           {
               _FileName = filename;
               CacheName = filename;
               HttpContext ctx = HttpContext.Current;
               FilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");
          ErrorLogFilePth = ctx.Server.MapPath("~/" + _FileName + ".txt");
              LoadHits();
          }

          /**//// <summary>
          /// 将累计点击数保存到全局变量,当它达到一定量时保存到文本文件,并清空
          /// </summary>
          public  void AddHits()
          {
              lock(LockForAddHits)
              {
                  if( Hits != 0 )
                  {
                      Add();
                      if(Hits > 200 )
                      {
                          //--移除                       
                          HttpRuntime.Cache.Remove(CacheName);
                      }
                  }
                  else
                  {
                      onRemove = new CacheItemRemovedCallback(ItemRemovedFromCache);
                      HttpRuntime.Cache.Insert(
                          CacheName,
                          "This Object For Expired",
                          null,
                          DateTime.Now.AddSeconds(5) ,
                          TimeSpan.Zero,
                          System.Web.Caching.CacheItemPriority.Normal,
                          onRemove
                          );
                      Add();                   
                  }
              }
          }           

          /**//// <summary>
          /// 保存到文本文件
          /// </summary>
          /// <param name="AllId"></param>
          private  void SaveHitsToFile(int hits)
          {
              string hitsinfo = string.Empty;           

              DateTime LastWriteTime = File.GetLastWriteTime(FilePth);
              if((DateTime.Today - LastWriteTime).TotalDays >0 )
              {
                  //--表示今天第一次写数据
                    HitsArr[1] = HitsArr[2];//--将当前累计的点击数赋给昨天的点击数
                    HitsArr[2] = hits;//--设置今天的点击数
                    using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )
                    {
                        streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1]   ,hits));
                        streamWriter.Flush();
                    }
                }
                else
                {
                    using(StreamWriter streamWriter = new StreamWriter(FilePth,false) )
                    {
                        streamWriter.Write(string.Format("{0},{1},{2}",HitsArr[0] + hits,HitsArr[1],     HitsArr[2] + hits));
                        streamWriter.Flush();
                    }
                }
            }   
           
            /**//// <summary>
            /// 当缓存被移除或过期是触发的回调事件
            /// </summary>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <param name="reason"></param>
            private  void ItemRemovedFromCache(string key, object value,CacheItemRemovedReason       reason)
            {
                try
                {
                    //清空并写到文本文件

                    #region 
                    int  hits = 0;;
                    lock(LockForItemRemovedFromCacheHits)
                    {
                        hits = Hits;
                        HitsArr[0] += hits;
                        HitsArr[2] += hits;
                        Hits = 0;
                    }
                    if(hits == 0)
                    {
                        return;
                    }
                    else
                    {
                        SaveHitsToFile(hits);
                    }               
                    #endregion
                }
                catch(Exception ex)
                {
                    using(StreamWriter streamWriter = new StreamWriter(ErrorLogFilePth,false) )
                    {
                        streamWriter.Write(string.Format("时间:{0}/r/n描述信息:{1}/r/n",DateTime.       Now,ex.Message));
                        streamWriter.Flush();
                    }
                }
            }

            /**//// <summary>
            /// 获取所有的点击数
            /// </summary>
            public int AllHits
            {
                get
                {
                    return HitsArr[0] + Hits;
                }
            }

            /**//// <summary>
            /// 获取昨天点击数
            /// </summary>
            public  int YesterdayHits
            {
                get
                {
                    return HitsArr[1];
                }
            }   

            /**//// <summary>
            /// 获取今天点击数
            /// </summary>
            public  int TodayHits
            {
                get
                {
                    return HitsArr[2] + Hits;
                }
            }

            /**//// <summary>
            /// 加载点击数
            /// </summary>
            private  void LoadHits()
            {
                if (HttpRuntime.Cache[CacheName] == null)
                {
                    HttpContext ctx = HttpContext.Current;
                    if (!File.Exists(FilePth))
                    {
                        //--第一次使用
                        using (StreamWriter streamWriter = new StreamWriter(FilePth))
                        {
                            streamWriter.Write(string.Format("{0},{1},{2}", 0, 0, 0));
                            streamWriter.Flush();
                        }
                        HitsArr[0] = 0;
                        HitsArr[1] = 0;
                        HitsArr[2] = 0;
                    }
                    else
                    {
                        string hitsinfo = string.Empty;
                        using (StreamReader objStreamReader = new StreamReader(FilePth))
                        {
                            hitsinfo = objStreamReader.ReadLine();
                        }
                        if (hitsinfo != "")
                     {
                         string[] arr = hitsinfo.Split(',');
                            HitsArr[0] = Convert.ToInt32(arr[0]);//全部
                            HitsArr[1] = Convert.ToInt32(arr[1]);//昨天
                            HitsArr[2] = Convert.ToInt32(arr[2]);//今天
                        }
                        else
                        {
                            HitsArr[0] = 0;
                            HitsArr[1] = 0;
                            HitsArr[2] = 0;
                        }
                    }
                    HttpRuntime.Cache["b" + CacheName] = HitsArr;
                }
                else
                {
                    HitsArr = (int[])HttpRuntime.Cache["b" + CacheName];
                    //HitsArr[0] += 1;
                    //HitsArr[2] += 1;

                }
            }


            /**//// <summary>
            /// 获取累计的点击数
            /// </summary>
            private  int Hits
            {
                get
                {
                    return    _Hits;
                }
                set
                {
                    _Hits = value;
                }
            }

            /**//// <summary>
            /// 累加
            /// </summary>
            /// <param name="id"></param>
            private  void Add()
            {
                if(HitsArr[2]<14000)
                {
                    //_Hits = _Hits + new Random(DateTime.Now.Second).Next(60,80);
                    _Hits = _Hits + 1;
                }
                else
                {
                    _Hits = _Hits + 1;//_Hits = _Hits + new Random(DateTime.Now.Second).Next(2,8);       传回指定范围的随机数
                }
            }
            /**//// <summary>
            /// 文件名
            /// </summary>
           
            /// <summary>
            /// 获取文件名
            /// </summary>
            public string FileName
            {
                get { return _FileName; }
                set { _FileName = value; }
            }
        }
    }


    2.创建HttpHandler

    <%@ WebHandler Language="C#" class="HttpHandler" %>

    using System;
    using System.Web;
    using System.Text.RegularExpressions;


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


            public bool IsReusable
            {
                get
                { return false; }
            }

        }
    }


    生成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>

    这里只介绍到写入文件,如果想写入库里面,直接读取文件里的数值就搞定!

  • 相关阅读:
    PAT (Advanced Level) 1080. Graduate Admission (30)
    PAT (Advanced Level) 1079. Total Sales of Supply Chain (25)
    PAT (Advanced Level) 1078. Hashing (25)
    PAT (Advanced Level) 1077. Kuchiguse (20)
    PAT (Advanced Level) 1076. Forwards on Weibo (30)
    PAT (Advanced Level) 1075. PAT Judge (25)
    PAT (Advanced Level) 1074. Reversing Linked List (25)
    PAT (Advanced Level) 1073. Scientific Notation (20)
    PAT (Advanced Level) 1072. Gas Station (30)
    PAT (Advanced Level) 1071. Speech Patterns (25)
  • 原文地址:https://www.cnblogs.com/Fooo/p/2581897.html
Copyright © 2011-2022 走看看