本文介绍搭建热更服务器并在手机上测试react native热更的全过程。
>>>我的博客<<<
安装MySQL
安装完成后,会弹出初始密码,粗细的我,随手点了OK,此处挖坑半天。
code-push热更服务器搭建:
安装code-push-server
- npm安装
# 安装code-push-server
npm install code-push-server -g
- 源码安装(推荐)
# 从git库下载最新代码
git clone https://github.com/lisong/code-push-server.git
# 进入到code-push-server目录
cd code-push-server
# 安装
npm install
Code-Push-Server配置
修改config/config.js文件,指定数据库,数据存放位置
- 配置数据库
db: {
username: "root",
password: "Your PWD",
database: "codepush",
host: "127.0.0.1",
port: 3306,
dialect: "mysql"
}
- 配置存储(默认为local,本次也采用local)
common: {
// dataDir用于进行存放比对文件
dataDir: "/Users/tablee/workspaces/data",
// 存储类型,可选值有local,oss,qiniu,s3
storageType: "local"
},
// 文件存储在本地 当storageType为local时需要配置
local: {
// 二进制文件存放目录,文件下载目录,不要使用临时目录
storageDir: "/Users/tablee/workspaces/storage",
// 文件下载地址 CodePushServer地址 + ’/download‘,download对应app.js里面的地址
//默认此处的下载地址是127.0.0.1:3000这个自然是错误的,要外网ip地址
downloadUrl: "https://tech.haier.net:7788/download",
// public static download spacename
public: '/download'
},
//七牛云存储配置 当storageType为qiniu时需要配置
qiniu: {
accessKey: "",
secretKey: "",
bucketName: "",
//文件下载域名地址
downloadUrl: ""
},
//阿里云存储配置 当storageType为oss时需要配置
oss: {
accessKeyId: "",
secretAccessKey: "",
endpoint: "",
bucketName: "",
// 对象Key的前缀,允许放到子文件夹里面
prefix: "",
// 文件下载域名地址,需要包含前缀
downloadUrl: "",
}
- 配置签名,可以不修改,但是推荐更改
jwt: {
// 登录jwt签名密钥,必须更改,否则有安全隐患,可以使用随机生成的字符串
// Recommended: 63 random alpha-numeric characters
// Generate using: https://www.grc.com/passwords.htm
tokenSecret: 'https://www.grc.com/passwords.htm'
}
初始化数据库
配置完成后,进行数据初始化工作
- npm安装
# 初始化数据库,**替换为数据库密码**(参考后面配置说明)
code-push-server-db init --dbhost localhost --dbuser root --dbpassword **Your PWD** --dbport 3306
- 源码安装
# 初始化数据库
./bin/db init --dbhost localhost --dbuser root --dbpassword **Your PWD** --dbport 3306
注意事项:
- 不论采取哪种安装方式,初始化数据库时要保证数据库用户名密码正确;数据库中不能存在codepush数据库(默认数据库为codepush)
- 采用源码安装,执行bin目录下的db命令时,要保证此文件具有可执行权限,如果没有,需要添加权限
# 添加db文件的可执行权限
chmod +x bin/db
- 如果数据库密码复杂,带有特殊符号,初始化语句将执行失败。此时因为是第一次安装,可以在数据库服务器手动创建名为
codepush
(必须是这个名字)的数据库,然后执行/opt/chuangke/code-push-server/sql/
目录下的codepush-all.sql
脚本来初始化数据库。
初始化成功后数据库中的表如下:
- 如果数据库密码复杂,带有特殊符号,初始化语句将执行失败。此时因为是第一次安装,可以在数据库服务器手动创建名为
服务启动
安装配置文件中的目录结构,到/Users目录中建立如下文件夹 /Users/tablee/workspaces/storage
- npm启动
# 启动服务,默认使用3000端口,可以在浏览器中打开 http://127.0.0.1:3000
code-push-server
# 指定端口号运行
PORT=3000 HOST=127.0.0.1 NODE_ENV=production code-push-server
- 源码启动
# 启动服务(保证www具有可执行权限),在浏览器中打开 http://127.0.0.1:3000
./bin/www
# 以守护进程的方式运行
nohup ./bin/www &
# 指定端口号运行
PORT=3000 HOST=127.0.0.1 NODE_ENV=production node ./bin/www
- forever 后台启动(推荐)
先安装forever
当然,有人说forever已经过时了,推荐使用pm2代替forever,请参考linux npm start 保持后台运行
# 全局安装
$ npm install forever -g
# 查看是否安装成功
$ forever list
info: No forever processes running
很抱歉,如果不顺利的话,会有这么个情况
[root@izm5e3m6sxwr4dw9w7r6h4z lib]# npm install forever -g
/opt/software/node-v10.0.0-linux-x64/bin/forever -> /opt/software/node-v10.0.0-linux-x64/lib/node_modules/forever/bin/forever
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/forever/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
+ forever@0.15.3
updated 1 package in 2.109s
[root@izm5e3m6sxwr4dw9w7r6h4z lib]# forever list
-bash: forever: 未找到命令
[root@izm5e3m6sxwr4dw9w7r6h4z lib]#
不美丽了,命名安装成功了,但是还是提示找不到命令,怎么办呢?我来教你,这个是因为这个-g是吧命令安装到了node所在目录,可以看看具体在哪
[root@izm5e3m6sxwr4dw9w7r6h4z ~]# npm list -g --depth 0
/opt/software/node-v10.0.0-linux-x64/lib
├── forever@0.15.3
└── npm@5.6.0
[root@izm5e3m6sxwr4dw9w7r6h4z ~]# cd /opt/software/node-v10.0.0-linux-x64/lib
[root@izm5e3m6sxwr4dw9w7r6h4z lib]# ls
node_modules
[root@izm5e3m6sxwr4dw9w7r6h4z lib]# cd node_modules/forever/bin/
[root@izm5e3m6sxwr4dw9w7r6h4z bin]# ls
forever monitor
[root@izm5e3m6sxwr4dw9w7r6h4z bin]#
这次是真的看见forever被安装到哪里,接下来就来个软链到/usr/bin
下就可以了
[root@izm5e3m6sxwr4dw9w7r6h4z bin]# ln -s /opt/software/node-v10.0.0-linux-x64/lib/node_modules/forever/bin/forever /usr/bin/forever
[root@izm5e3m6sxwr4dw9w7r6h4z bin]# forever list
info: No forever processes running
[root@izm5e3m6sxwr4dw9w7r6h4z bin]#
完美,接着使用forever启动应用啦。
比如我的server源码的位置在/opt/chuangke/code-push-server/
,在当前目录下执行如下命令启动
NODE_ENV=production forever start -l log/forever.log -o log/info.log -e log/err.log bin/www
可以用如下绝对路径命令启动:
NODE_ENV=production forever start -l /opt/chuangke/code-push-server/log/forever.log -o /home/haieradmin/codepush/code-push-server/log/info.log -e /home/haieradmin/codepush/code-push-server/log/err.log /home/haieradmin/codepush/code-push-server/bin/www
- 服务启动验证
命令行验证
$ forever list
info: Forever processes running
data: uid command script forever pid id logfile uptime
data: [0] 8Or8 /usr/local/node8/bin/node /opt/chuangke/code-push-server/bin/www 60199 60209 /opt/chuangke/code-push-server/log/forever.log 0:15:2:21.503
如果服务器启动成功,则用浏览器访问默认的3000端口,可以看到如下效果
到此服务器端到配置就完成了。
客户端热更验证
客户端测试代码以 https://github.com/lisong/code-push-demo-app 为例
客户端安装code-push-cli
# 全局安装
$ npm install -g code-push-cli
# 查看版本
$ code-push -v
2.1.8
下载客户端验证程序,并安装第一版
- clone程序并install
$ git clone git@github.com:lisong/code-push-demo-app.git
# cd 到demo路径,执行npm install 安装node依赖包
$ cd code-push-demo-app
$ npm install
打开命令终端,登录code-push-server服务器,这里配置为local,所以登录地址为http://127.0.0.1:3000
$ code-push login http://127.0.0.1:3000 //账号密码为博主提供 account: admin password: 123456
登录成功之后获取token
将文本框中的key复制粘贴到登录终端,点击回车登录成功
输入账号密码,点击登录。获取token:
$ code-push login http://127.0.0.1:3000
Please login to Mobile Center in the browser window we've just opened.
Enter your token from the browser: HugyOJpzvzhEhB05galUftoL4zrz4ksvOXqog
Successfully logged-in. Your session file was written to C:\Users\marvin\AppData\Local\.code-push.config. You can run the code-push logout command at any time to delete this file and terminate your session.
在命令行查看当前热更服务器的部署信息,
$ code-push app list
┌──────┬─────────────┐
│ Name │ Deployments │
└──────┴─────────────┘
- 添加新的APP(以安卓为例)
# 安卓版
$ code-push app add CodePushReactNativeDemo-android react-native
Successfully added the "CodePushReactNativeDemo-android" app, along with the following default deployments:
┌────────────┬───────────────────────────────────────┐
│ Name │ Deployment Key │
├────────────┼───────────────────────────────────────┤
│ Production │ VKNbn9Oe5Wj9bPoGkYCUVuzRuqHV4ksvOXqog │
├────────────┼───────────────────────────────────────┤
│ Staging │ 6KfLoVvhgdsnFzFCIohRb2t5grmD4ksvOXqog │
└────────────┴───────────────────────────────────────┘
# 再运行命令查看
$ code-push app list
┌─────────────────────────────────┬─────────────────────┐
│ Name │ Deployments │
├─────────────────────────────────┼─────────────────────┤
│ CodePushReactNativeDemo-android │ Production, Staging │
└─────────────────────────────────┴─────────────────────┘
- 修改配置
添加完成之后可以用code-push app list命令查看创建好的app,并将测试的Staging key拷贝到MainApplication.java中的 “Your Key“ 的位置,推送的时候通过key将app和服务器端关联。
- 修改配置
用Android Studio打开code-push-demo-app/android
目录到MainApplication.java里面修改以下代码:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CodePush(
"YourKey", // code-push app add项目后生成的app 推送key
MainApplication.this,
BuildConfig.DEBUG,
"YourCodePushServerUrl" // config.js中配置的downloadUrl 地址 不需要/download后缀
)
);
}
我的配置是:
修改MainApplication.java的代码如下:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CodePushBuilder(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey),getApplicationContext())
.setIsDebugMode(BuildConfig.DEBUG)
.setServerUrl(getResources().getString(R.string.reactNativeCodePush_androidServerURL))
.build()
);
}
修改android/app/src/main/res/values/strings.xml文件,指定reactNativeCodePush_androidDeploymentKey和reactNativeCodePush_androidServerURL。
<resources>
<string moduleConfig="true" name="reactNativeCodePush_androidDeploymentKey">6KfLoVvhgdsnFzFCIohRb2t5grmD4ksvOXqog</string>
<string moduleConfig="true" name="reactNativeCodePush_androidServerURL">http://xxx.xxx:3000/</string>
<string name="app_name">CodePushDemoApp</string>
</resources>
- cd 到code-push-demo-app目录,允许react-native start 启动react-native 服务。可以选择用数据线连接手机,手机开启开发者模式。也可以直接将
code-push-demo-app\android\app\build\outputs\apk\debug
以后的apk包发送到手机上,直接打开安装。
- cd 到code-push-demo-app目录,允许react-native start 启动react-native 服务。可以选择用数据线连接手机,手机开启开发者模式。也可以直接将
$ react-native run-android
在手机上运行app的截图如下:
-
Android Studio编译并将项目运行到手机上,reload更新到最新js包在code-push-demo-app中首页随意做一些修改,这里是将CodePushDemoApp/App.js文件做了如下修改。
执行推送命令
-
# 测试环境执行:
$ code-push release-react CodePushReactNativeDemo-android android --t 2.1.0 --d Staging --des "热更测试" -m false
Detecting android app version:
Using the target binary version value "2.1.0" from "android\app\build.gradle".
Running "react-native bundle" command:
node node_modules\react-native\local-cli\cli.js bundle --assets-dest C:\Users\marvin\AppData\Local\Temp\CodePush\CodePush --bundle-output C:\Users\marvin\AppData\Local\Temp\CodePush\CodePush\index.android.bundle --dev false --entry-file index.js --platform android
Scanning folders for symlinks in D:\Git\oschina\react\code-push-demo-app\node_modules (101ms)
Scanning folders for symlinks in D:\Git\oschina\react\code-push-demo-app\node_modules (48ms)
Loading dependency graph, done.
bundle: Writing bundle output to: C:\Users\marvin\AppData\Local\Temp\CodePush\CodePush\index.android.bundle
bundle: Done writing bundle output
bundle: Copying 1 asset files
bundle: Done copying assets
Releasing update contents to CodePush:
Successfully released an update containing the "C:\Users\marvin\AppData\Local\Temp\CodePush\CodePush" directory to the "Staging" deployment of the "CodePushReactNativeDemo-android" app.
# 生产环境执行:
$ code-push release-react CodePushReactNativeDemo-android android -d Production
#指定版本,添加注释
$ code-push release-react CodePushReactNativeDemo-android android -d Production --des "marvin code push testing" -t "1.0.0"
Successfully 表示热更包推送成功,然后在手机上点击Press for dialog-driven sync链接。
弹出下载确认
点击【install】
至此,热更服务器搭建,及android版app体验完毕。
扩展
1、产看更新包安装情况
# code-push deployment history appName deploymentName
code-push deployment history CodePushReactNativeDemo-android Staging
Staging 或者 Production
2、列表部署名称
code-push deployment ls CodePushReactNativeDemo-android
3、常见错误
3.1、 download地址写错,默认是http://127.0.0.1:3000 如果不改成外网域名和端口,下载将失败。
app启动抓包查看的结果就是,返回的下载地址无法下载到资源。
3.2、nginx限制资源大小
需要修改配置,我们的一个app打包后约70M,上传时就报错了,后来才知道是nginx指定的上传大小是50M,所以要修改nginx配置文件,加上client_max_body_size 100M;
这个样配置。
3.3、数据库配置错误
将数据库的端口,或者用户名密码写错也很常见
3.4、目录权限问题
配置文件里默认的dataDir和storeage目录必须有code-push运行用户的操作权限,否则会有以下错误。
常用命令
// 账户相关
code-push login 登陆
code-push loout 注销
code-push access-key ls 列出登陆的token
code-push access-key rm <accessKye> 删除某个 access-key
// app操作相关
code-push app add <appName> <platform> react-native 在账号里面添加一个新的app
code-push app remove 或者 rm 在账号里移除一个 app
code-push app rename 重命名一个存在 app
code-push app list 或则 ls 列出账号下面的所有 app
code-push app transfer 把app的所有权转移到另外一个账号
// 应用信息相关
code-push deployment add <appName> 部署
code-push deployment rm <appName> 删除部署
code-push deployment rename <appName> 重命名
code-push deployment ls <appName> 列出应用的部署情况
code-push deployment ls <appName> -k 查看部署的key
code-push deployment history <appName> <deploymentName> 查看历史版本
// 发布
code-push release-react <appName> <platform> -t 版本 -d 环境 --des 描述 -m true (强制更新)
// 清除历史部署记录
code-push deployment clear <appName> Production or Staging
// 回滚
code-push rollback <appName> Production --targetRelease v4(codepush服务部署的版本号)
- 注意事项:
更新规则
1> CodePush部署版本 > App版本
更新可用,但当前版本比运行版本高。不作更新
2> CodePush部署版本 < App版本
不执行更新处理
3> CodePush部署版本 == App版本
自动下载更新,并根据加载策略加载最新bundle回滚
当部署的版本不同时,不能跨版本回滚。
例如:CodePush历史版本中为2.10.1,此时发布2.10.2版本。当从2.10.2发起回滚操作回到2.10.1时,是不可行的。
- 部署信息参数
在部署了版本之后,执行 【code-push deployment ls uniApp-Android】可以查看当前版本、当前部署环境下的部署信息:
- Update Metadata(更新信息)
Label:标识当前部署版本,每部署新版本,版本号增加1
App Version:当前部署的App版本号
Mandatory:是否强制更新
Release Time:部署时间
Released By:部署用户
Description:部署 描述信息
从上面内容不难发现,这些信息基本都会在我们执行 code-push release 时配置
- Install Metrics(安装指标)
Active:成功安装并运行当前release的用户的数量,即表示当前下载更新部署的活跃用户数量,of 左边数会随着用户安装、卸载而 增加、减少。of右边数代表当前安装或收 到部署版本的用户数,当有用户卸载App,该数值会降低。
因此它很好的解释了当前更新包有多少活跃用户,多少用户接收过这个安装包
Total:成功安装部署当前release的用户量,只增不减
Pending:当前release版本被下载的数量,但是还没有被安装,该值会随着用户下载安装后增加, 在卸载时降低。
参考资料
code-push-server 搭建自己的推送服务器流程
热更新(android)windows系统code-push-server 的使用
ReactNative集成CodePush教程 集成Code Push的案例说明
react-native热更新全方位讲解