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

前言

   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[n];
                        
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[n];
                        
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

 

转载于:https://www.cnblogs.com/walkingboy/archive/2009/01/13/ScriptLoaderV5.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值