CSDN助手源码剖析(一)--缓存优化

一、引言

1、为什么,csdn的帖子后面要加个temp查询字符串。
2、为什么,同一个帖子,“temp”查询字符串会经常发生变化。
3、为什么,Internet缓存目录会过度膨胀。

二、背景

  CSDN帖子采用xml文件进行存储,下载时也直接下载xml文件。这样做有许多好处。比如,1、实现数据与显示的分离:数据的更新与显示页面的维护都非常方便;2、减少网络传输:显示页面(xsl文件)只需要下载一次,数据文件(xml文件)也非常的短小,因此帖子打开显示的速度很快。

  但使用xml文件同时要考虑一个缓存的问题。由于xml文件是一个静态文件,当浏览器第一次访问之后,会将其缓存至临时目录,下一次访问时,可能不会再访问服务器,而直接从缓存读取。如果在真实的URL地址后面加上临时的、随机的查询字串,那么浏览器通过这个URL在缓存中找不到,就会访问服务器,读取最新的数据。

  大家可以测试一下,随便在“temp=”后面输入任何数字,或直接将“temp=”删除,都会访问到xml文件。为了保证用户总是能通过不同的URL访问最新的帖子,至少存在以下两个机制:

  1. 不直接提供形如“xml?temp=xxxx”的URL(简称“地址A”),而是提供形如“topicview1.asp?id=4854274”的URL(简称“地址B”)。地址B,浏览器不缓存,总是能访问服务器,而服务器则根据需要生成随机的地址A,传给浏览器,通过重定向,取得最新的xml文件。
  2. 为了避免频繁的改变地址A,至少当帖子更新后,必须重新生成一个temp查询字符串。

 三、两难境地

  基于以上的分析,访问同一个帖子,将会对应地产生多个地址A,也就会在浏览器的临时目录中缓存多个帖子副本。显然,只有最后一个副本有意义(脱机时),以前的是多余的,不再可能被访问的。可能有人会想,为什么不通过在服务器端设置头部“Cache-Control:no-cache”,从而阻止浏览器缓存xml文件呢?一个简单的理由是,为了支持在脱机时能够访问以前访问过的xml文件,必须使用缓存。

  于是,这将出现一个两难境地。如果为了节约缓存,那么就不会使用“temp”这项技术,就有可能不能访问最新的数据;如果为了总是能访问到最新的数据,就会在临时目录缓存大量重复的数据。

四、解决方案

  “CSDN助手”通过一个桥接技术,很好的解决了这个“两难问题”。
举例:
地址A:http://community.csdn.net/Expert/topic/4854/4854274.xml?temp=.5251428
地址B:http://community.csdn.net/expert/topicview1.asp?id=4854274
地址C:http://community.csdn.net/expert/cache/4854274.xml

  1. 截获浏览器对“地址A”和“地址B”的访问,通过URL Moniker技术,自己访问服务器,取得数据文件后,以“地址C”的名义缓存至临时目录。这样,当浏览器再次访问“地址A”和“地址B”时,由于在缓存中找不到,所以仍然会再次访问服务器。而“地址C”针对同一个帖子是唯一的,所以确保缓存中只有唯一的副本。
  2. 怎样支持脱机:截获浏览器对“地址A”和“地址B”的访问,先判断是否处于脱机状态。如不是,则进行步骤1;如是,则通过“地址C”在缓存中找到副本直接打开。

五、URL Moniker

  前面讲到,截获浏览器对“地址A”和“地址B”的访问,自己访问服务器,从而有效的控制缓存的处理。自己访问服务器,读取数据文件,可以有多种技术。我们分析一下他们的特点,决定到底用哪一种技术:

  1. Socket函数:最底层(也是相对而言)的访问方法,需要构造Request,分解Response,需要编码、解码,而且不支持系统提供的通过代理访问服务器的能力。
  2. wininet函数:系统级的函数,支持代理,灵活性强,但考虑的细节过多。
  3. Msxml2.XMLHTTP组件:封装了许多细节,调用方便,但不支持客户端对缓存的控制。有许多人在进行Ajax开发时,对这个组件“不支持客户端缓存控制”的特点颇有微词。对缓存的控制,经常需要服务器的配合。显然,开发“CSDN助手”不应该对服务器要求过多。
  4. URL Moniker对象:URL Moniker提供了一种建立并使用URL的框架,初次接触时感觉不太好理解,但实际上很好控制,支持代理,支持客户端的缓存控制,相对wininet函数而言,细节比较少。

  事实上,在“CSDN助手”的早期版本,由于没有过多考虑“缓存优化”的细节,采用了“Msxml2.XMLHTTP组件”进行数据的读取。由于组件的自身限制,不得不在其他的几项技术中选中了“URL Moniker对象”。

  关于“URL Moniker对象”的实现细节,请参考

CSDN助手源码剖析(二)--URL Moniker的封装

六、相关函数

  为节省篇幅,下面仅列出主要的函数与方法,便于“下断点跟踪”,源码下载请转到:http://blog.csdn.net/seasol/archive/2006/07/04/873747.aspx

  1. function fn_shell_callback(oWindow,oUrl,oTarget)
    位于“程序集/CSDNAssist/default.asps”文件中,用于截获浏览器对“地址A”和“地址B”的访问。
  2. CCSDNTools::topicviewPrecheck(BSTR bstrURL, BSTR* pbstrValue)
    检测是否处于脱机状态,如果是,则直接返回缓存中的副本。
  3. CCSDNTools::topicview(BSTR bstrUrl,VARIANT varDisp, BSTR bstrTarget, long nType,IDispatch* pDispCallback)
    启动帖子的异步下载。
  4. CCSDNTools::func_topicviewResponseProc(void* pParam1,CParam_Http_Base* pParam2,CCuteHttpBase* pHttpBase,IStream* pStream)
    当帖子下载完成时调用的回调函数。
  5. CCSDNTools::SaveToCache(IStream* pStream,LPCTSTR szUrl,LPCTSTR szUrlCache,LPCTSTR szTopicID,CString& sCacheFile)
    将帖子缓存至Internet临时目录。

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值