Silverlight:xap包(或本地缓存)下载版本更新的解决思路
在SL开发中,通常会将项目按模块分成多个xap实现按需下载,但是由于浏览器的缓存,就算某个模块代码修改过并重新发布到服务器,如果这个xap已经在浏览器缓存中,实际加载时,仍然有可能调用的是本地缓存,而非最新的版本。
通常解决这个问题的办法是在xap包的下载地址后附加一个随机数,类似http://xxx.com/abc.xap?t=1235817232 之类。但是这样相当于强制浏览器每次去重新下载xap文件,缓存机制被完全给干掉了,特别是对于一些大型项目,xap通常比较大,每次重新下载,需要较长时间,用户的体验非常差。
相对比较科学的方法是用"版本号"来替换"随机数",比如http://xxx.com/abc.xap?v=20101001
每次发布时,更新版本号即可。但是修改版本号这种体力活儿,最好由机器自动完成,而不是靠人来完成。
为此,我们先做创建一个自动生成版本号的工具:GenVersion.exe,它是一个Console Application,代码极其简单
using System;
using System.IO;
namespace GenVersion
{
class Program
{
static void Main(string[] args)
{
string _fileName = "Version.txt";
if (args.Length > 0)
{
_fileName = args[0];
}
File.WriteAllText(_fileName, DateTime.Now.ToString("yyyyMMddHHmmss"));
}
}
}
注:这里我们用日期字符串做为版本号.
接下来,我们利用vs.net的生成事件,在每次编译成功时,自动调用这个exe,在website的Version目录下生成Version.txt
如下图:
关键是:call $(ProjectDir)VersionGenVersion.exe $(ProjectDir)VersionVersion.txt 这一条指令.
注:Version目录下如何编译时不能自动更新Version.txt文件,请检测该文件夹是否有写权限。
自动生成版本号的问题解决了,SL如何使用服务端的这个版本号呢?
SL端Loading项目的处理逻辑如下:
1、先检测本地独立存储(也可以用Cookie来存储)中的客户端版本信息,得到客户端版本号ClientVersion 2、再去加载服务端的Version.txt,得到服务端的版本号ServerVersion 3、对比二个版本号,声明一个变量,取二个版本号的最大值,保存在MaxVersion中。 4、加载主模块xap包时,用类似http://www.xxx.com/SL_App.xap?v=MaxVersion 的Uri加载 5、下载完成后,将MaxVersion保存到本地独立存储(或Cookie中),以方便下次对比。
以上思路,不仅仅适用于处理XAP的按需加载,同步也适用于独立存储中的缓存数据,有时候我们会把一些不经常更新的数据以文件形式保存在客户端本地作为数据缓存,同样也会遇到版本更新的问题。
解决的方法很简单:
类似以上的做法,在缓存文件的第一行记录版本号,然后在调用本地缓存之前,取服务端版本号对比,如果发现服务端的版本更新,则更新本地缓存,否则直接使用本地缓存。
示例源码下载:http://files.cnblogs.com/yjmyzz/VersionSample.7z
- [数据库基础]——编码标准之结构
- 2017前端开发手册三-前端职位描述
- [.NET自我学习]Delegate 泛型
- [数据库基础]——图解JOIN
- ubuntu搭建内网穿透服务Ngrok
- SQL Server 性能优化之——T-SQL 临时表、表变量、UNION
- node.js 学习笔记
- SQL Server 性能优化之——T-SQL TVF和标量函数
- C# 6.0 功能预览 (一)
- [译]Asp.net MVC 之 Contorllers(二)
- [译]Asp.net MVC 之 Contorllers(一)
- Oracle 学习笔记
- [数据库基础]——索引详解
- [数据库基础]——快速浏览日期时间转换
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【剑指offer】47.求1+2+3+...+n
- 【剑指offer】48.不用加减乘除做加法
- Gradle 6.6 发布,引入配置缓存特性,大幅提升构建性能
- 61.Vue 结合webpack使用vue-router
- 拨云见日:揭开ORA-00600:[4193]的神秘面纱
- AUCell | 识别单细胞对“基因集”的响应
- 未来十年,机器学习工程师会消失吗?
- Get了!用Python制作数据预测集成工具 | 附代码
- 定时任务最简单的3种实现方法(超好用)
- Swift:UICollectionReusableView xib创建报错
- echo-高性能,可扩展,极简的Go Web框架
- 小程序文字显示换行
- css Backgroud-clip (文字颜色渐变)
- 微信小程序 buton清除默认样式
- 正则replace 回调函数里接收的参数是什么?