緩衝篇(Cache)~第三回 HttpModule實現網頁的檔案級緩衝

來源:互聯網
上載者:User

標籤:style   blog   http   color   io   os   使用   ar   for   

返回目錄

再寫完緩衝篇第一回之後,得到了很多朋友的好評和來信,所以,決定加快步伐,儘快把剩下的文章寫完,本篇是第三回,主要介紹使用HttpModule實現的檔案級緩衝,在看本文之前,大家需要限度HttpModule有一個瞭解,可以先看我的這篇文章《開發人員應該對IIS理論層的知識瞭解的多一些~第四講 HttpModule中的幾大事件》

對於檔案級緩衝來說,我們要知道兩點,一為檔案的URL,二為檔案的

下面是HttpModuleCache的核心代碼

/// <summary>    /// CacheHttpModule類    /// </summary>    internal class CacheHttpModule : IHttpModule    {        public void Dispose()        {        }        private List<string> listNeedCacheExtend;        private string stringClearCache = "zzl";//網域名稱中第一段 url 如果是此字元,則表示此次請求是清除緩衝 如: http://www.domain.com/zzl/*******        public void Init(HttpApplication context)        {            context.BeginRequest += new EventHandler(context_BeginRequest);            context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);            listNeedCacheExtend = new List<string>();            string extends = WebConfig.GetUserSection("CacheInfo", "ExtendTypes", ".html|.htm");            foreach (string s in extends.Split(‘|‘))            {                if (!string.IsNullOrEmpty(s) && !listNeedCacheExtend.Contains(s.Trim()))                    listNeedCacheExtend.Add(s.Trim());            }        }        public void context_BeginRequest(object sender, EventArgs e)        {            var application = (HttpApplication)sender;            if (IsNeedCache(application)) //檢測當前請求是否需緩衝            {                string key = string.Empty; ;                string extend = VirtualPathUtility.GetExtension(application.Context.Request.FilePath).ToLower();                if (IsClearCache(application, out key))                {                    if (CacheManage.Container(key, extend))//緩衝中存在,則清除緩衝,結束請求                    {                        application.Context.Response.Write(CacheManage.Remove(key, extend));                    }                    application.CompleteRequest();                }                else                {                    #region 使用頁面壓縮                    ResponseCompressionType compressionType = this.GetCompressionMode(application.Context.Request);                    if (compressionType != ResponseCompressionType.None)                    {                        application.Context.Response.AppendHeader("Content-Encoding", compressionType.ToString().ToLower());                        if (compressionType == ResponseCompressionType.GZip)                        {                            application.Context.Response.Filter = new GZipStream(application.Context.Response.Filter, CompressionMode.Compress);                        }                        else                        {                            application.Context.Response.Filter = new DeflateStream(application.Context.Response.Filter, CompressionMode.Compress);                        }                    }                    #endregion                    if (CacheManage.Container(key, extend))//緩衝中存在,則直接返回內容,結束請求                    {                        CacheManage.Write(application, key);                        application.CompleteRequest();                    }                }            }        }        /// <summary>        /// 檢測當前請求是否需緩衝,如果是則將此次結果添加至緩衝,如果此次請求出錯,不會執行至此        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        public void context_ReleaseRequestState(object sender, EventArgs e)        {            var application = (HttpApplication)sender;            if (application.Context.Response.StatusCode == 200)            {                string strT = null;                string extend = VirtualPathUtility.GetExtension(application.Context.Request.FilePath).ToLower();                if (IsNeedCache(application) && !IsClearCache(application, out strT))                {                    string key = application.Context.Request.Url.AbsoluteUri;                    //是否需要添加緩衝,                    if (!CacheManage.Container(key, extend))                    {                        application.Context.Response.Filter = new ResponseFilter(application.Context.Response.Filter, key, extend, application.Context.Response.ContentEncoding);                    }                }            }        }        public void context_EndRequest(object sender, EventArgs e)        {            var application = (HttpApplication)sender;            string key = application.Context.Request.Url.AbsoluteUri;            application.Context.Response.Write("<Br>CacheMdule EndRequest");        }        /// <summary>        /// 檢測當前請求類型(url副檔名)確定是否需緩衝        /// 如果類型需緩衝,但副檔名是html或htm且存在相對應的物理檔案的,不執行快取作業        /// </summary>        /// <param name="strFilePath"></param>        /// <returns></returns>        private bool IsNeedCache(HttpApplication application)        {            bool boolNeedCache = false;            string stringExtend = VirtualPathUtility.GetExtension(application.Context.Request.FilePath).ToLower();            if (null != listNeedCacheExtend) //url副檔名是否滿足條件            {                boolNeedCache = listNeedCacheExtend.Contains(stringExtend);            }            if (boolNeedCache)            {                if (stringExtend == ".html" || stringExtend == ".htm")                {                    if (System.IO.File.Exists(application.Context.Request.PhysicalPath)) //存在對應物理檔案                    {                        boolNeedCache = false;                    }                }            }            return boolNeedCache;        }        /// <summary>        /// 檢測當次請求是否是清除緩衝的         /// True 清除緩衝  False  不是清除緩衝的        /// </summary>        /// <param name="application"></param>        /// <param name="url">真實的URL地址</param>        /// <returns></returns>        private bool IsClearCache(HttpApplication application, out string url)        {            bool boolClearCache = false;            url = application.Context.Request.Url.AbsoluteUri;            string domain = application.Context.Request.Url.Host;            Regex regex = new Regex("http://" + domain + "/" + stringClearCache + "/", RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);            if (regex.IsMatch(url))            {                boolClearCache = true;                url = "http://" + domain + "/" + url.Replace(regex.Match(url).Captures[0].Value, string.Empty);            }            return boolClearCache;        }        /// <summary>        /// 擷取用戶端支援的壓縮類型        /// </summary>        /// <param name="request"></param>        /// <returns></returns>        private ResponseCompressionType GetCompressionMode(System.Web.HttpRequest request)        {            string acceptEncoding = request.Headers["Accept-Encoding"];            if (string.IsNullOrEmpty(acceptEncoding))                return ResponseCompressionType.None;            acceptEncoding = acceptEncoding.ToUpperInvariant();            if (acceptEncoding.Contains("GZIP"))                return ResponseCompressionType.GZip;            else if (acceptEncoding.Contains("DEFLATE"))                return ResponseCompressionType.Deflate;            else                return ResponseCompressionType.None;        }        private enum ResponseCompressionType        {            None, GZip, Deflate        }    }

對於上面的HttpModule來說,還需要在config檔案中進行相應的配置,代碼如下

  <modules runAllManagedModulesForAllRequests="true" >      <add name="CacheHttpModule" type="HttpModuleCache.CacheHttpModule,HttpModuleCache"/>    </modules>

程式運行後當檢測到合法的檔案後(如你之前對html和shtml結尾的檔案進行緩衝),就會組建檔案到伺服器的指定位置,下次訪問時,直接通過URL產生的伺服器本地路徑,將靜態檔案返回到用戶端即可,不過,有個地方要注意,由於這種方法產生的快取檔案,它的位置不是固定的,所以,在引用CSS,JS這種檔案時,要用絕對路徑的形式。

沒有用絕對路徑時

用了絕對路徑後

怎麼樣,這種檔案級緩衝的方式大家都掌握了吧!

下載完整HttpModuleCache項目

返回目錄

 

緩衝篇(Cache)~第三回 HttpModule實現網頁的檔案級緩衝

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.