java 网页刷新 小程序_java实现的客户端自更新自重启小程序

java实现的客户端自更新自重启小程序,程序实现一个client,访问升级服务器配置,根据服务器的配置下载升级包,部署,重启服务。

3940d041fe0afbfb5298ddbc032f8164.png

Update接收启动停止命令控制自身生成和被管理程序

Updatemanager判断是否需要升级,升级的版本比较,升级包的下载和比对,升级包的解压发布和被升级服务的重启任务

Packexecuter 管理需要升级的process,主要是启动停止被管理process

Update作为程序的主入口必须一直在后台运行。被管理process原则上只能通过update程序启动停止,update程序作为管理程序必须要有较高的稳定性,尽量保持功能的简洁,防止崩溃,如果update崩溃,process可能还在后台运行,需要第三方杀死被管理process。或者在重启主程序时做判断当前是否已经有未杀死的process

Update.java

private static final String CMD_EXIT = "/exit";

public static String JarCmd="process startup";//jar包的启动命令 java -jar C\:app.jar

private static Update sUpdate;

public static void main(String[] args) {

String serverIP = PropertiesUtil.getValue("serverIP");

int serverPort = 0;

try {

serverPort = Integer.parseInt(PropertiesUtil.getValue("serverPort", "88"));

} catch (Exception e) {

System.out.println("端口必须是数字");

return;

}

System.out.println("正在启动...");

UpdaterMagager updater = new UpdaterMagager ();

updater.start(serverIP, serverPort);

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

while (true) {

String cmd = null;

try {

Thread.sleep(3000);

cmd = br.readLine();

} catch (Exception e) {

System.out.println("控制台IO异常");

break;

}

if (cmd == null) {

continue;

}

if (CMD_EXIT.equals(cmd)) {

break;

}

System.out.println("未知的命令");

}

sUpdate.exit();

PackExecutor.exit();

System.out.println("bye");

}

public void start(String ip, int port) {

sUpdate = new UpdaterMagager (ip, port);

sUpdate.start();

}

UpdaterMagager.java

private static final long CHECK_TIME = 5 * 60 * 1000L;//检测时间

private static final String CODE_UPDATE = "1"; // 是否更新标志

private String mServerIP = null;

private int mServerPort = 0;

private boolean mKeepThread = false;

private String savepath=PropertiesUtil.getValue("savepath");

private String unzippath= PropertiesUtil.getValue("unzippath");

private static String versionname;

public UpdaterMagager(String ip, int port) {

mServerIP = ip;

mServerPort = port;

}

public void start() {

mKeepThread = true;

new Thread(this).start();

}

public void exit() {

mKeepThread = false;

}

//通过zip生成md5的值

private String getFileMd5(String filePath) {

File f = new File(filePath);

if (!f.exists()) {

return null;

}

try {

byte[] data = new byte[(int) f.length()];

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));

int readLen = 0;

do {

int len = bis.read(data, readLen, data.length - readLen);

if (len == -1) {

data = null;

break;

}

readLen += len;

} while (readLen < data.length);

bis.close();

return Md5Utils.md5Hex(data);

} catch (Exception e) {

}

return null;

}

public void run() {

PackExecutor.execute();

BufferedInputStream bis = null;

BufferedOutputStream bos = null;

long st = 0L;

long waitTime = CHECK_TIME;

while (mKeepThread) {

try {

Thread.sleep(5000L);

} catch (Exception e) {

}

//System.out.println("正在检查更新...");

try {

File f = new File(savepath);

if(!f.exists()){

f.mkdir();

}

//获取当前机器在升级服务器的配置,返回result是json格式

String result= GetIpAddress.getInfo("http://" + mServerIP + ":" + mServerPort + "/update/getAppidByAppurl", 5000);

if(StringUtils.isBlank(result)){

continue;

}

//获取服务器需要升级的版本,是否需要升级

String appversionname = null;

if (StringUtils.isNotBlank(result)) {

JSONObject res = new JSONObject(result);

appversionname=res.get("appversionname")+"";

} else {

System.out.println("appversionname为空,无法更新");

}

if(StringUtils.isBlank(appversionname)||"null".equals(appversionname)){

continue;

}

if(StringUtils.isBlank(versionname)){

versionname=appversionname;

}

String filepath=savepath+"/"+appversionname;

if(StringUtils.isNotBlank(versionname)){//版本改动时,不做md5判断,直接下载zip包,更新程序

if(!versionname.equals(appversionname)){

String urlStr = "http://" + mServerIP + ":" + mServerPort + "/update/getZip?filename="+appversionname;

if(GetIpAddress.downloadFilebyUrl(urlStr, 60000, filepath));

//解压zip文件到需要升级的目录

ZipUtil.unzip(filepath, unzippath);

//重启被管理进程

PackExecutor.stop();

PackExecutor.execute();

versionname=appversionname;

continue;

}

}

//如果版本检测无需升级,检测同一zip包的是否有变化,MD5检测

String res = GetIpAddress.getInfo("http://" + mServerIP + ":" + mServerPort + "/update/getZipmd5?md5="+getFileMd5(filepath)+"&filename="+appversionname, 5000);

if (StringUtils.isNotBlank(res) && CODE_UPDATE.equals(res)) {

// 有更新,下载zip,重启服务

String urlStr = "http://" + mServerIP + ":" + mServerPort + "/update/getZip?filename="+appversionname;

if(GetIpAddress.downloadFilebyUrl(urlStr, 60000, filepath));

//解压zip文件到小卫星目录

ZipUtil.unzip(filepath, unzippath);

//重启小卫星

PackExecutor.stop();

PackExecutor.execute();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

PackExecutor.java

private static boolean sExit = false;

private static Process sProcess = null;

private static BufferedWriter sProcessBW = null;

private static String unzippath= PropertiesUtil.getValue("unzippath");

//杀死子进程

public synchronized static void exit() {

sExit = true;

if (sProcess != null) {

try {

if (sProcessBW != null) {

System.out.println("正在杀死子进程...");

sProcessBW = new BufferedWriter(new OutputStreamWriter(sProcess.getOutputStream()));

sProcessBW.write("/exit");

sProcessBW.newLine();

sProcessBW.flush();

sProcessBW.close();

sProcessBW = null;

Thread.sleep(10000L);

}

if (sProcess != null) {

sProcess.destroy();

}

} catch (Exception e) {

if (sProcess != null) {

System.out.println("杀死子进程失败");

return;

}

}

sProcess = null;

System.out.println("杀死子进程成功");

}

}

//停止子进程

public synchronized static void stop() {

if (sExit) {

return;

}

if (sProcess != null) {

try {

if (sProcessBW != null) {

sProcessBW = new BufferedWriter(new OutputStreamWriter(sProcess.getOutputStream()));

sProcessBW.write("/stop");

sProcessBW.newLine();

sProcessBW.flush();

System.out.println("正在停止子进程服务...");

Thread.sleep(10000L);

}

} catch (Exception e) {

System.out.println("停止子进程服务失败");

return;

}

System.out.println("停止子进程服务成功");

}

}

public synchronized static void execute() {

if (sExit) {

return;

}

new Thread(new Runnable() {

public void run() {

//重启时如果子线程未杀死,先杀子进程

if (sProcess != null) {

try {

if (sProcessBW != null) {

sProcessBW = new BufferedWriter(new OutputStreamWriter(sProcess.getOutputStream()));

sProcessBW.write("/exit");

sProcessBW.newLine();

sProcessBW.flush();

sProcessBW.close();

sProcessBW = null;

System.out.println("正在杀死子进程...");

Thread.sleep(10000L);

}

if (sProcess != null) {

sProcess.destroy();

sProcess = null;

}

System.out.println("杀死子进程成功");

} catch (Exception e) {

System.out.println("杀死子进程失败");

} finally {

try {

if (sProcessBW != null) {

sProcessBW.close();

sProcessBW = null;

}

if (sProcess != null) {

sProcess.destroy();

sProcess = null;

}

} catch (Exception e) {

}

}

}

System.out.println("正在启动子进程...");

try {

sProcess = Runtime.getRuntime().exec(Updater.JarCmd,null,new File(unzippath));

sProcessBW = new BufferedWriter(new OutputStreamWriter(sProcess.getOutputStream()));

sProcessBW.write("/start");

sProcessBW.newLine();

sProcessBW.flush();

System.out.println("子进程运行中...");

//新建一个线程,用来输出正确的日志

new Thread(new Runnable() {

public void run() {

BufferedReader br = null;

try {

br = new BufferedReader(new InputStreamReader(sProcess.getInputStream()));

String s = null;

System.out.println("控制台INFO:");

while ((s = br.readLine()) != null) {

System.out.println(s);

}

br.close();

} catch (Exception e) {

e.printStackTrace();

} finally {

if (br != null) {

try {

br.close();

} catch (Exception e) {

}

br = null;

}

}

System.out.println("控制台INFO结束");

}

}).start();

//新建一个线程,用来输出错误的日志

new Thread(new Runnable() {

public void run() {

BufferedReader br = null;

try {

br = new BufferedReader(new InputStreamReader(sProcess.getErrorStream()));

String s = null;

System.out.println("控制台ERR:");

while ((s = br.readLine()) != null) {

System.out.println(s);

}

br.close();

} catch (Exception e) {

e.printStackTrace();

} finally {

if (br != null) {

try {

br.close();

} catch (Exception e) {

}

br = null;

}

}

System.out.println("控制台ERR结束");

}

}).start();

sProcess.waitFor();

System.out.println("子进程已终止...");

} catch (Exception e) {

e.printStackTrace();

try {

if (sProcessBW != null) {

sProcessBW.close();

sProcessBW = null;

}

if (sProcess != null) {

sProcess.destroy();

sProcess = null;

}

} catch (Exception e1) {

}

System.out.println("子进程启动失败");

return;

}

}

}).start();

}

升级服务器的配置是ip,版本号和升级包,先到这儿,有时间再更

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值