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>

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

  • 相关阅读:
    Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) D
    HDU 2036 求任意多边形面积板子题
    HDU 6703 array(主席树)
    2019牛客暑期多校训练营(第九场)H Cutting BamboosO(二分、主席树)
    lintcode-425-电话号码的字母组合
    lintcode-81-数据流中位数
    lintcode-424-逆波兰表达式求值
    lintcode-423-有效的括号序列
    lintcode-422-最后一个单词的长度
    lintcode-421-简化路径
  • 原文地址:https://www.cnblogs.com/Fooo/p/2581897.html
Copyright © 2011-2022 走看看