视频播放用户行为记录之使用Cache的方法
在上一篇文章http://www.cnblogs.com/ryuasuka/p/3483632.html中,为了获取视频播放时的用户行为,并且要异步地将其写入XML文件中,我采用了先写入log,后生成XML文件的方法。这个方法的缺点就在于当大量用户访问的时候生成的log会加重服务器的负担。而今天看到一篇文章讲Cache的用法http://www.cnblogs.com/lin714115/archive/2013/04/07/3003643.html,突然就想试一试如果使用Cache是不是能省去很多代码和文件呢?
为了便于说明,我写了个Demo。一个aspx页面(事实上html页面也可以),一个ashx一般处理程序。Aspx页面的核心部分如下:
时间:<input id="currentTime" type="text" /><input id="aButton" type="button" value="button" /> <input id="toFile" type="button" value="Get File" /> <script type="text/javascript"> $('#aButton').click(function () { $('#currentTime').val(Date()); $.post("/MyHandler.ashx", { type:"data",data: $('#currentTime').val() }, function() {}); }); $('#toFile').click(function() { $.post("/MyHandler.ashx", { type: "submit" }, function() {}); }); </script>
单击button获得当前系统时间并实时地在ashx文件中进行XmlDocument对象的节点写入。单击Get File按钮生成XML文件。
ashx代码如下:
private XmlDocument doc; private XmlElement root; public void ProcessRequest(HttpContext context) { if (context.Request["type"] == "data") // 写入数据 { // 从Cache中读入doc对象 doc = context.Cache["file"] as XmlDocument; if (doc == null) // 若没有就新建一个 { doc = new XmlDocument(); XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "UTF-8", null); doc.AppendChild(decl); context.Cache["file"] = doc; // 初始化完毕之后在Cache中保存doc对象 } // 从Cache中读入root对象 root = context.Cache["root"] as XmlElement; if (root == null) // 若没有就新建一个 { root = doc.CreateElement("video"); doc.AppendChild(root); context.Cache["root"] = root; // 同样保存一下 } // 写入数据 XmlElement time = doc.CreateElement("time"); time.InnerText = context.Request["data"]; root.AppendChild(time); } else if (context.Request["type"] == "submit") // 生成XML { // 从Cache中读入之前保存的doc对象 doc = context.Cache["file"] as XmlDocument; if (doc != null) { doc.Save(context.Server.MapPath("time.xml")); } } }
代码中,每次发起Http请求都先从Cache中读入先前保存的doc和root(doc是XmlDocument对象,root是XmlElement对象,因为要执行root.AppendChild操作,因此要保存一下root)。如果读入的对象为null,则通过构造方法新建一个对象,完成初始化之后立刻将其保存入cache,这样下一次请求的时候Cache中就有内容了。
从代码中可以看到,使用Cache避免了文件的大量读写,使得操作都在内存中进行,提高了程序效率。同时,Cache可以存储任何类型的数据(在代码中体现为Object类型),这就为规模较大的数据的传递提供了基础。
但是这种做法也有一个缺点,那就是当发起请求中包含了”no-cache”,那么Cache就不会起作用了。