您的位置:首页 > 运维架构

[OpenSource] ScriptLoader V5:不一样的体验,客户端分布式缓存平台

2009-01-13 21:15 155 查看
前言
ScriptLoader断断续续也开发了半年多了, 很多朋友都觉得这样的项目花俏多于实用, 其实有一个很重要的功能一直都没有开发,那就是我在[OpenSource]ScriptLoaderV2:彻底改变你的编程习惯提到过的ClientCacheManager.

在开发中,每个人都或多或少的使用了Cache,为了减少数据库的负担,或者为了增加处理请求的速度.但是使用Cache也是一件很麻烦的事情,必须维护真实数据与缓存的同步,必须根据查询命中率判断Cache优先级有的放矢的删除低效缓存项,必须维护所有缓存对象的可序列化,必须维护服务器群集间的缓存同步......

只不过,这些缓存的处理大部分都是在Server端.在RIA横行的今天,我们是否忽视了成千上万的客户端?当Ajax+Json支撑起很多系统的时候,我们是否应该可以更好的利用Browser的缓存机制来减少请求的次数,降低资源的消耗,获得更快的速度?

客户端缓存的真正意义,在于减少网络请求,降低数据库查询,充分利用Server的内存,增加Application的吞吐量和请求处理效率,同时也可以提高客户端的响应速度,因为数据本来就存在客户端嘛^_^. 同时,缓存在客户端的东西,即使服务器重启亦可以持久保留.在现在这个大硬盘高内存为标配的PC时代,已经没啥人去手工清理IE缓存了,所以搞不好1年下来,它都一直用着同一个缓存呢:)

基于ScriptLoader的缓存控制原理,ScriptLoaderV5,将带入走入这样一个被忽视的世界,带给你一个简单但用处颇多的客户端分布式缓存平台.

插件接口

ScriptLoader在V5之前,只能算是一个Library,但现在它已经成为一个小的Framework,它同样可以管理外部插入的ScriptObject对象,并管理其版本的更新.

IPlugin的定义很简单.

namespace LangZi.Scripts

{

public interface IPlugin

{

//Get the json data

string GetContent();

//Get the last modified datetime of the live data

DateTime GetLastModified();

}

}

公共方法:

为了对Plugin进行管理,ScriptLoader同样新增了几个方法

1.LoadPlugin

看得出来,跟以前版本中的LoadStylesheet一样,只是封装了下Load的方法而已

服务端:

public void LoadPlugin(string fileName)

{

Load(fileName + ".Plugin");

}
客户端:

function LoadPlugin(name){

Load(name+".plugin");

}

2.RefreshPlugin:

手工更新某个指定的Plugin的数据和版本信息. 当然ScriptLoader还有一个自动的维护Plugin版本信息的轮询机制.

public void RefreshPlugin(string pluginName)

3.配置项:

Plugin版本更新的轮询间隔时间:如果不配置,默认是180000;//30 minutes

<appSettings>

<add key="VersionUpdateTime" value="50000"/>

</appSettings>
Plugin部署配置

<configSections>

<sectionGroup name="LangZi">

<section name="ScriptLoaders" type="System.Configuration.NameValueSectionHandler"/>

</sectionGroup>

</configSections>

<LangZi>

<ScriptLoaders>

<add key="Locations" value="ScriptLoader.Plugins.Location,ScriptLoader.Plugins"/>

</ScriptLoaders>

</LangZi>

<httpHandlers>

<add verb="GET" path="*.plugin" type="LangZi.Scripts.ScriptLoaderHandler,LangZi.ScriptLoader"/>

</httpHandlers>

应用场景演示:

我相信很多人都做过省市联动控件,举这样一个例子,每个人都会比较熟悉.所以我开发了一个演示性的Plugin:



Location.cs

using System;

using System.Collections.Generic;

using System.Text;

using LangZi.Scripts;

using System.Xml;

using System.Web;

using System.IO;

namespace ScriptLoader.Plugins

{

public class Location:IPlugin

{

#region IPlugin Members

public string GetContent()

{

StringBuilder data = new StringBuilder();

/*

var locations = [{Name:'FuJian',City:[{Name:'XiaMen'},{Name:'FuZhou'}] } ,{Name:'BeiJing',City:[{Name:'ChongWen'},{Name:'ChaoYang'}]}];

*/

data.Append("var locations = [");

XmlDocument doc = new XmlDocument();

var filename = System.AppDomain.CurrentDomain.BaseDirectory+ "location.xml";

doc.Load(filename);

XmlNode node = doc.SelectSingleNode("/China");

for(int i=0;i<node.ChildNodes.Count;i++)

{

XmlNode item = node.ChildNodes[i];

if(i==0)

{

data.AppendFormat("{{Name:'{0}',City:[", item.Name);

for (int n = 0; n < item.ChildNodes.Count; n++)

{

XmlNode city = item.ChildNodes
;

if (n == 0)

{

data.AppendFormat("{{Name:'{0}'}}", city.Name);

}

else

{

data.AppendFormat(",{{Name:'{0}'}}", city.Name);

}

}

data.Append("]}");

}

else

{

data.AppendFormat(",{{Name:'{0}',City:[", item.Name);

for (int n = 0; n < item.ChildNodes.Count; n++)

{

XmlNode city = item.ChildNodes
;

if (n == 0)

{

data.AppendFormat("{{Name:'{0}'}}", city.Name);

}

else

{

data.AppendFormat(",{{Name:'{0}'}}", city.Name);

}

}

data.Append("]}");

}

}

data.Append("];");

return data.ToString();

}

public DateTime GetLastModified()

{

var filename = System.AppDomain.CurrentDomain.BaseDirectory + "location.xml";

FileInfo fi = new FileInfo(filename);

return fi.LastWriteTime;

}

#endregion

}

}

Location.xml

<?xml version="1.0" encoding="utf-8" ?>

<China>

<FuJian>

<FuZhou></FuZhou>

<XiaMen>

<SiMing></SiMing>

<HuLi></HuLi>

<TongAn></TongAn>

<JiMei></JiMei>

<HaiCang></HaiCang>

</XiaMen>

<QuanZhou>

<AnXi></AnXi>

<NanAn></NanAn>

<YongChun></YongChun>

<JinJiang></JinJiang>

<ShiShi></ShiShi>

</QuanZhou>

<ZhangZhou></ZhangZhou>

</FuJian>

<Shanghai>

<HuangPuQu></HuangPuQu>

<PuTuoQu></PuTuoQu>

</Shanghai>

<BeiJing>

<ChongWen></ChongWen>

<ChaoYang></ChaoYang>

</BeiJing>

</China>

消费Plugin:

protected void Page_Load(object sender, EventArgs e)

{

LangZi.Scripts.ScriptLoader loader = LangZi.Scripts.ScriptLoader.RegisterInstance(this);

loader.LoadPlugin("Locations");

}

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>Untitled Page</title>

<script type="text/javascript">

function Get(id){

return document.getElementById(id);

}

function SelectedProvinceOnChange(value){

var currentProvince;

for(i=0;i<locations.length;i++){

if(locations[i].Name == value){

currentProvince = locations[i];

break;

}

}

var cities = Get("cities");

for(i = cities.options.length-1;i>-1;i--){

cities.options.remove(i)

}

if(currentProvince != null){

for(i=0;i<currentProvince.City.length;i++){

var option =new Option(currentProvince.City[i].Name);

cities.options.add(option);

}

}

}

function OnInit(){

var Provinces = Get("provinces");

for(i=0;i<locations.length;i++){

var option =new Option(locations[i].Name);

Provinces.options.add(option);

}

SelectedProvinceOnChange(locations[0].Name);

}

</script>

</head>

<body onload="OnInit()">

<form id="form1" runat="server">

<div>

Province:

<select id="provinces" onchange="SelectedProvinceOnChange(this.options[this.selectedIndex].text)">

</select>

City:

<select id="cities">

</select>

<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />

</div>

</form>

</body>

</html>

远期计划

ScriptLoader开发到这个版本,已经接近我的思维极限了,后续的开发暂时找不出更大的突破,或许只是小修小补,比如对缓存的控制进一步精细,把目前的缓存控制周期进行分割,新增其他的周期,例如基于Page的周期(比Context长,但是比Session短,离开页面即失效).或者将ScriptObject的范畴扩展出去,包括任何Broswer可缓存的对象(image......).

当然,基于组件的应用,那可想像的空间还是很大的,但这不能算是ScriptLoader的原生功能.

所以说,如果到如今,你还找不到ScriptLoader在你的项目中的应用场景的话,那请忽略它,因为暂时我无能力再突破它,增加更新鲜的功能.

09年,或许是我开源的一年,如果你对ScriptLoader不感兴趣,可以关注我的另一个开源项目LangZi.QuickCMS,当然目前这个项目只完成了一个组件LangZi.Web.UrlEngine,如果对UrlRewriter比较在乎的朋友,小瞄一下或许你会有不一样的收获^_^.

资源下载

1.svn: https://scriptloader.svn.sourceforge.net/svnroot/scriptloader

2.packages: http://code.google.com/p/langzi/downloads/list
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐