Hydra 自动更新说明
源自RemObjects Wiki
[http://wiki.remobjects.com/wiki/Hydra_Autoupdate_Explained]
This is a Hydra for Delphi Articles topic
Feel free to add your notes to this topic below.
无论你写什么类型的程序,很多都要在其生命周期中进行更新。而使用Hydra插件框架就很更频繁遇到,但它们不再需要完全重新部署了。
Hydra Server2中提供了两个控件集和两个已经编译好的可执行文件模块,使用它们可以为你的应用程序提供远程自动更新的特性.本文介绍其如何工作
继续之前要提到一点,Hydra为这两个自动更新的可执行文件提供了源码,你可以直接使用也可以进行定制,如本地化,制作自己的Logos等。也可将这些代码加入到你自己的应用程序中。但如果时间紧迫或不想过于麻烦,可以直接使用它们.
目录
|
马上实现自动更新
Hydra自动更新非常简单,当应用程序启动后,特定的控件(THYAutoUpdateClient)将向服务端发送一个UpdateID字符串进行请求。这个UpdateID含客户端最后获取更新的标识信息,服务端将使用它判断是否有新的内容需要发送到客户端。这个更新过程会增加程序启动的负担,当然通常这是可以忽略的,通过完整的检查请求,可以给很多应用程序带来益处.
如果服务端应答说这里有新的更新,客户端将发送一个文件列表,服务端返回包括文件需要被下载和更新的信息的文件列表。
客户端开始下载,一旦完成,新的文件将覆盖原有文件.
自动更新细节
在客户端下载更新时,将在指定目录中生成一些临时文件.
例如,如果你的主要执行文件叫做TestApp.exe,并要下载其新版本,Hydra自动更新模块将在同目录下生成一个$$TTestApp.exe文件,将获取的数据保存到其中。这种临时文件的命名是可以控制的,可以修改前缀$$.
这提供了很多好处,首先,可以立即在应用程序目录中看到什么文件正在下载。删除临时文件也很简单。它们不依赖与注册表或Ini配置文件.
最主要的特性是可以重新启动下载。这样就可以发出中断下载指令,在方便的时候继续下载,而不会影响现有的文件.
THYAutoUpdateClient 组件
THYAutoUpdateClient 组件在Hydra组件标签中:
THYAutoUpdateClient 继承自标准的RO组件 TRORemoteService ,并添加了几个扩展属性,用来控制从哪里下载,如何将当前文件信息发送给服务端.
如下截图是TAutoUpdateClient控件的属性:
如图所见,其连接到标准的RemObjects SDK channel和message控件,也具有一个ServiceName 属性. 下面是其他和事件的详细信息:
DownloadBufferSize (integer) |
每个文件都是增量下载的,这个属性指定每个下载块的大小. OnDownloadProgress事件可以用来显示下载状态和更新进度条. |
TemporaryFileNamePrefix (string) |
指定临时文件的前缀,详见"Autoupdate in more detail". |
ServiceName |
连接到任意的TRORemoteService 组件,指向一个远程服务的名称. 这里需要注意的是这个服务必须从特定类型THYAutoUpdateService继承(更多信息后面详述). |
FileSearchInfo |
这个属性指定如何生成一个发送到服务端的文件列表.这个属性在服务端也很关键,在需要的时候将会描述. |
TAutoUpdateClient
现在看看使用这个控件是多么的简单。下面是Hydra的自动更新客户端的截图:
点击Check for Updates 按钮将触发如下代码:
function TAutoUpdateMainForm.CheckForUpdates : boolean;
begin
result := FALSE;
fCanResume := FALSE;
FreeAndNIL(fUpdates);
try
// 从服务端获取更新列表并保存在私有字段"fUpdates"(THYFileUpdateInfoArray)
// 属性(Updates指向它)中. Updates有一个属性设置方法SetUpdates,
//将更新应用程序主窗体的listview.
Updates := AutoUpdateClient.GetUpdatesInfo(fUpdateID, fCanResume);
StatusMessage := '';
finally
result := (Updates<>NIL) and (Updates.Count>0);
end;
actCheckUpdates.Visible := not result;
actDownloadUpdates.Visible := result;
end;
可见,只需要一行代码.
这个方法执行后,假设服务端存在需要更新的内容,应用程序截图如下所示:
我们可以点击"Download Updates"按钮指向如下代码:
procedure TAutoUpdateMainForm.actDownloadUpdatesExecute(Sender: TObject);
begin
AutoUpdateClient.DownloadUpdates(Updates);
end;
非常漂亮!这些代码(和触发的组件事件),允许我们用最高的效率显示更新过程.
自动更新,服务端
就如客户端代码一样简介,服务端代码同样简单,除非你要定制服务端处理复杂更新情形.
如基于Data Abstract 的服务,启动时调用很多预编译的功能来引用一些RODL文件,在这里使用的是由Hydra 2提供的AutoUpdateLibrary.RODL,.
这个 RODL 文件定义了一些用于交换文件信息的类型,和基础服务THYAutoUpdateService, 接口如下:
{ IHYAutoUpdateService }
IHYAutoUpdateService = interface
['{39330BB5-9B50-41B5-AC92-854FC48DD748}']
function VerifyUpdateStatus(const LastUpdateID: String;
out UserData: String): THYUpdateStatus;
function GetUpdatesInfo(const UpdateID: String;
const ClientFiles: THYFileUpdateInfoArray): THYFileUpdateInfoArray;
function GetFileData(const UpdateInfo: THYFileUpdateInfo;
const Offset: Integer; const Count: Integer; out Data: Binary): Integer;
end;
引用AutoUpdateLibrary RODL,只需要在基类服务中继承,就可以生成自动更新服务,如下图:
很优雅. 编译这个服务项目,就可以得到从THYAutoUpdateService继承来的服务,并提供自动更新和发送文件到客户端的必要属性和方法.
如下所示:
AutoUpdateLibrary RODL中提供的类型如下:
{ THYFileUpdateInfo }
THYFileUpdateInfo = class(TROComplexType)
[..]
published
property Operation:THYUpdateOperation
read fOperation write fOperation;
property FileName:String read fFileName write fFileName;
property Size:Integer read fSize write fSize;
property TimeStamp:DateTime read fTimeStamp write fTimeStamp;
property Version:String read fVersion write fVersion;
property DownloadProgress:Integer
read fDownloadProgress write fDownloadProgress;
property UserData:String read fUserData write fUserData;
end;
{ THYFileSearchInfo }
THYFileSearchInfo = class(TROComplexType)
[..]
published
property SearchMask:String read fSearchMask write fSearchMask;
property Recursive:Boolean read fRecursive write fRecursive;
property TargetClientDirectory:String
read fTargetClientDirectory write fTargetClientDirectory;
end;
现在看一下THYFileSearchInfo 类型的集合--FileSearchInfo属性, 这个属性在服务端和客户端都和关键.
FileSearchInfo
下图所示是属性FileSearchInfo典型的设置:
这个属性中存储了用于在服务端和客户端生成文件列表的目录信息集合.本例中,服务端目录"$APPLICATION/Update.1/ApplicationDir/*.*"目录与客户端目录$APPLICATION对应,"$APPLICATION/Update.1/WindowsDirUpdates/*.*"与$WINDOWS目录对应.
为了易于理解,考虑到我们说的"Autoupdate at a glance"章节.当客户端发送一个文件列表,服务端接收到一个含文件名如"$APPLICATION/TestApp.exe" 和 "$WINDOWS/MyCustomDLL.DLL"的THYFileUpdateInfo类型对象集合.因为 SearchMask指定为"$APPLICATION/Update.1/ApplicationDir/*.*" ,及 TargetClientDirectory为"$APPLICATION",服务端在"$APPLICATION/Update.1/ApplicationDir/目录查找TestApp.exe.在"$APPLICATION/Update.1/WindowsDirUpdates"目录查找MyCustomDLL.DLL.
注意宏$APPLICATION 指向应用程序指向文件目录.其他宏是$SYSTEM 和 $WINDOWS 指向相关系统目录.
总结
Hydra的自动更新特性提供了部分更新功能(使用插件)而不需重新部署. 无需写多少代码就可以实现断点续传的下载功能.