feat(update): проверка версии UI через Ping без периодических опросов

This commit is contained in:
AidarKC
2026-04-22 19:57:59 +03:00
parent 1a8d1c70fd
commit 78d6124f2a
5 changed files with 72 additions and 100 deletions
@@ -7,12 +7,26 @@ import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_Ping_Request;
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_Ping_Response;
import server.logic.ws_protocol.WireCodes;
import utils.config.AppConfig;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Ping — keep-alive.
* В ответ кладём только ts (текущее время сервера в мс).
* В ответ кладём:
* - ts (текущее время сервера в мс)
* - uiBuildHash (текущий build hash UI, если удалось определить)
*/
public class Net_Ping_Handler implements JsonMessageHandler {
private static final AppConfig CONFIG = AppConfig.getInstance();
private static final String DEFAULT_UI_INDEX_PATH = "/home/user/docker/caddyFile/sites/shine-UI/index.html";
private static final Pattern UI_HASH_PATTERN = Pattern.compile("window\\.__SHINE_BUILD_HASH__\\s*=\\s*'([^']+)'");
private static volatile String cachedUiBuildHash = "";
private static volatile long cachedUiIndexMtimeMs = -1L;
@Override
public Net_Response handle(Net_Request baseRequest, ConnectionContext ctx) {
@@ -25,7 +39,33 @@ public class Net_Ping_Handler implements JsonMessageHandler {
// ничего не проверяем, просто отдаём серверное время
resp.setTs(System.currentTimeMillis());
resp.setUiBuildHash(resolveUiBuildHash());
return resp;
}
}
private static String resolveUiBuildHash() {
String indexPathRaw = CONFIG.getParam("server.ui.indexPath");
String indexPath = (indexPathRaw == null || indexPathRaw.isBlank())
? DEFAULT_UI_INDEX_PATH
: indexPathRaw.trim();
try {
Path path = Path.of(indexPath);
long mtime = Files.getLastModifiedTime(path).toMillis();
if (mtime == cachedUiIndexMtimeMs && !cachedUiBuildHash.isBlank()) {
return cachedUiBuildHash;
}
String html = Files.readString(path, StandardCharsets.UTF_8);
Matcher matcher = UI_HASH_PATTERN.matcher(html);
String found = matcher.find() ? String.valueOf(matcher.group(1)).trim() : "";
cachedUiIndexMtimeMs = mtime;
cachedUiBuildHash = found;
return found;
} catch (Exception ignored) {
String fallback = CONFIG.getParam("server.ui.buildHash");
return fallback == null ? "" : fallback.trim();
}
}
}
@@ -8,13 +8,20 @@ import server.logic.ws_protocol.JSON.entyties.Net_Response;
* "op": "Ping",
* "requestId": "req-1",
* "status": 200,
* "payload": { "ts": 1700000000123 }
* "payload": {
* "ts": 1700000000123,
* "uiBuildHash": "20260422164933"
* }
* }
*/
public class Net_Ping_Response extends Net_Response {
private long ts;
private String uiBuildHash;
public long getTs() { return ts; }
public void setTs(long ts) { this.ts = ts; }
}
public String getUiBuildHash() { return uiBuildHash; }
public void setUiBuildHash(String uiBuildHash) { this.uiBuildHash = uiBuildHash; }
}