2023年11月26日发(作者:)

Electron-⾃动升级总结

1. 概述

本⽂介绍electron应⽤的在线升级⽅案调研和开发。

2. 客户端升级⽅案探讨

客户端升级⽅案

如上图,通过三个⽅⾯讨论⼀下在线升级的⼏个概念

2.1. 带宽因素

带宽的⼤⼩,直接关系到安装包的下载时长。

带宽因素,其实也就是安装包的体积因素,所以,尽量⽣成的安装包。

⾼压缩⽐

Electron应⽤的字段,可配置安装包的⾼压缩⽐:

build

{

"build": {

"asar": true,

"compression": "maximum",

⽅法1,每次Release需要⽣成与的diff⽂件,当Client发起Update请求时,对⽐OldVersion和NewVersion的差别⽂件,并打

历史所有版本

包Response给Client

⽅法2,基于Release包打包作为增量升级包,例如。于是,如果更新了其他⽂件的话,只能强制全量更新

经常变动的⽂件

⽅法3,对⽐单⽂件差异,然后只下载差异block即可

installer

结论:开发⿇烦,增加了在线升级的复杂度,性价⽐低,项⽬前期不建议

Electron应⽤如何⽀持

增量更新

Electron-updater采⽤上述⽅法3,更新机制和详细⽇志可以参考的⽇志

1

2.2. ⽤户量

对于活跃⽤户量很⼤的应⽤,灰度发布很有必要,不论客户端还是服务端

如果是项⽬初期,⽤户量并不多,功能并不复杂,变动⼤,⽽且经常迭代更新,全量发布会减少项⽬的迭代负担,更早发现问题、解决问题

当然,前提是测试要充分,让⽤户发现问题是下下策

全量发布

针对所有⽤户发布

灰度发布

只针对部分⽤户发布,可以随机20%发布,也可以基于⽤户Tag发布(前提是有可⽤的⽤户Tag)

Electron应⽤如何⽀持

灰度发布

Electron应⽤在的基础上,也可以⽀持,三个点:

electron-updater灰度发布

grayReleased: 80

增加⾃定义字段,⽐如

客户端每次启动,⾃动获取是否有可⽤的update,以及其详细信息,即

客户端本地随机⽣成100以内的⾃然数,如果⼩于80,则提⽰升级或⾃动升级,否则不升级

2.3. 兼容性

强制更新

启动时,⾃动⽆感更新

这种情况,⼀般是服务端的升级已不再⽀持旧版本,Electron应⽤的实现机制

启动时,⾃动可选更新

的最后⼀步,如果,⽤户可选择是否⽴即更新

强制更新CurrentVersion >= minVersionSupported

启动后,⼿动检测更新

⼀般情况下,在客户端会提供⼀个Page,供⽤户⼿动查看当前版本、检测是否有新版本,以及执⾏⽴即更新

2.4. 其他问题

2.4.1. 新版本的变更内容

仿照的做法,可以修改来实现

灰度发布强制更新

Electron⽀持Github Release的Release-Notes,对其他server不⽀持,所以只能⽤上⾯workaround

set electron-updater releaseNotes at build time

/electron-userland/electron-builder/issues/1511

2.4.2. 客户端安装失败后怎么办

这个问题很严重,主要是对终端的适配问题,于是,测试⼯作就显得尤为重要

如果真在⽤户端发⽣了,需要具体问题具体分析了

如何及时捕获到异常,并告知到服务端

如何回滚到旧版本,让⽤户先⽤着

HTTP(s) server).

You need only 2 lines of code to make it work.

import { autoUpdater } from "electron-updater"

orUpdatesAndNotify()

Electron-updater的优缺点:

优点

版本更新检查基于中的version字段值,⽀持三段式的版本号,⽆法定制

包含在线升级功能,实现了版本检查逻辑及回调、下载安装升级逻辑

⽀持多种版本服务器,包括⾃搭建的

通⽤服务器

⽀持alpha/beta/latest版本更新策略

⽀持增量更新,实现了增量更新失败时转全量更新的策略(⽬前只有windows版的,项⽬组据说计划增加mac版本的增量更新)

⽀持构建时⾃动发布版本到服务器

*⽀持降级更新

4.2. ⾃动打包发布

修改,增加字段如下,会读这个字段

增加⽂件,内容如下,存储MinIO的秘钥

buildelectron-builder

# publish to minio witch is s3-likely storage server

AWS_ACCESS_KEY_ID=xxx

AWS_SECRET_ACCESS_KEY=wJalrXUtnFENG/bxxR12CYxxxwwEXAMPLEKEY

执⾏即可打包和发布

yarn electron-builder --publish always

publish[0].path是auto-updater默认的feedurl,不能包含,必须指向最新版本的和安装包

${version}

publish[1]会⾃动上传安装包到MinIO,主要⽤于备份

publish[2]只是⽣成了,并不会⾃动上传,需要⾃动上传功能,需要通过js调⽤electron-builder实现。可⼿动move到http-

server的⽬录下即可,也可以采⽤electron-release-server

推荐采⽤MinIO作为release-server,可以⾃动publish,提⾼效率

"allowElevation": true,

"perMachine": false,

"allowToChangeInstallationDirectory": true,

"installerIcon": "./build/icons/",

image

5. 客户端⾃动更新开发

基于electron-updater完成开发,直接上代码

这⾥补充⼏点:

sion()

不work的话,可以这样⼦

import { version } from '../../../'

import { app } from 'electron'

sion = () => version

代码⾥⾯的,就是的数据,样例如下

info

{

version: '0.0.7',

files: [

{

url: '',

sha512: '795pdq9/Lt9MuANpM3tChxpCtzsqNe4v2wWyK41kUJ3PABHJns2xo5Jw46CWFOOCEVes57L5lmXV9v4NWNBeXg==',

size: 62858586

}

],

import { app, dialog } from 'electron'

import { autoUpdater } from "electron-updater"

import log from 'electron-log'

= "debug"

= log

function updateHandle() {

('client version', sion())

wnload = false

('error', (error) => {

rorBox('Error: ', error == null ? "unknown" : ( || error).toString())

})

('checking-for-update', () => {

('Checking for update')

});

('update-available', (info) => {

('Got a new client version, will auto download it', info)

adUpdate()

})

('update-not-available', (info) => {

('Current version is up-to-date', info)

})

('update-downloaded', (info) => {

(info)

ssageBox({

type: 'info',

从下⾯的log可以,可以看到只下载了⼤⼩的⽂件内容,体积不到4MB:

7%Full: 61,385.34 KB, To download: 4,103.49 KB (7%)

⼀次客户端升级的完整⽇志

[2021-06-30 15:27:03.799] [info] client version 0.0.6

[2021-06-30 15:27:03.807] [info] Checking for update

[2021-06-30 15:27:13.150] [info] Found version 0.0.7 (url: )

{

[2021-06-30 15:27:16.634] [info] New version 0.0.7 has been downloaded to C:UsersAdministratorAppDataLocalfoxchat-updaterpendingFoxChat-win-0.0.7-setup