收到 welcome 后才发 GetFileVer 2. 日志格式统一为 yyyy-MM-dd HH:mm:ss.fff 收到/发送消息:json

This commit is contained in:
zqm
2026-04-08 10:52:47 +08:00
parent e439084286
commit a6bd104635
3 changed files with 199 additions and 83 deletions

View File

@@ -6,6 +6,7 @@ version = 4
name = "Updater"
version = "0.1.0"
dependencies = [
"chrono",
"cube_lib",
"dirs",
"serde",
@@ -24,6 +25,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.102"
@@ -41,6 +51,12 @@ dependencies = [
"syn",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bitflags"
version = "2.11.0"
@@ -56,6 +72,12 @@ dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
[[package]]
name = "byteorder"
version = "1.5.0"
@@ -84,6 +106,19 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chrono"
version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-link",
]
[[package]]
name = "core-foundation"
version = "0.10.1"
@@ -343,6 +378,30 @@ version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "icu_collections"
version = "2.2.0"
@@ -470,6 +529,16 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
version = "0.3.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
@@ -576,6 +645,15 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.4"
@@ -805,6 +883,12 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "schannel"
version = "0.1.29"
@@ -1254,6 +1338,51 @@ dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b"
dependencies = [
"unicode-ident",
]
[[package]]
name = "wasm-encoder"
version = "0.244.0"

View File

@@ -9,6 +9,7 @@ serde_json = "1.0"
dirs = "5.0"
tokio = { version = "1.37", features = ["full"] }
windows = { version = "0.56", features = ["Win32_System_Console"] }
chrono = "0.4"
# Local CubeLib for WebSocket
cube_lib = { path = "../../../Rust/CubeLib" }

View File

@@ -151,36 +151,61 @@ async fn run_updater(debug_mode: bool) {
let mut client = WebSocketClient::new(config);
// 设置连接成功回调
let debug_clone = debug_mode;
let debug_connected = debug_mode;
client.on_connected(move |url| {
if debug_clone {
println!("[已连接] {}", url);
if debug_connected {
let ts = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
println!("{} 收到消息:{}", ts, url);
}
});
// 设置消息接收回调
let debug_for_msg = debug_mode;
client.on_message(move |msg_type, data| {
if debug_for_msg {
// 以标准 JSON 字符串格式输出日志
println!("[消息] {}", serde_json::to_string(&data).unwrap_or_else(|_| data.to_string()));
let debug_msg = debug_mode;
let device_number = resolve_device_number();
client.on_message(move |msg_type, data, sender| {
let ts = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
if debug_msg {
// 收到消息日志Type 在前
let data_str = serde_json::to_string(&data).unwrap_or_else(|_| "{}".to_string());
println!("{} 收到消息:{{\"Type\":{},\"Data\":{}}}",
ts,
serde_json::to_string(&msg_type).unwrap_or_default(),
data_str
);
}
// 收到 welcome 后,发送 GetFileVer
if msg_type == "welcome" {
if !device_number.is_empty() && device_number != "UNKNOWN" {
let msg_str = format!(
r#"{{"Type":"GetFileVer","Data":{{"DeviceNumber":"{}","file_list":["BootLoader.exe"]}}}}"#,
device_number
);
if debug_msg {
let ts2 = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
println!("{} 发送消息:{}", ts2, msg_str);
}
sender.send(msg_str);
}
}
// 处理 FileVer 响应
if msg_type == "FileVer" {
if let Some(file_versions) = data.get("Data").and_then(|d| d.get("file_versions")).and_then(|v| v.as_object()) {
for (filename, version) in file_versions {
let ver_str = version.as_str().unwrap_or("");
println!("[版本] {} = {}", filename, if ver_str.is_empty() { "未知" } else { ver_str });
println!("{} [版本] {} = {}", ts, filename, if ver_str.is_empty() { "未知" } else { ver_str });
}
}
}
});
// 设置断开连接回调
let debug_for_disconnect = debug_mode;
let debug_disconnect = debug_mode;
client.on_disconnected(move || {
if debug_for_disconnect {
println!("[断开] 连接已断开");
if debug_disconnect {
let ts = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
println!("{} [断开] 连接已断开", ts);
}
});
@@ -189,90 +214,57 @@ async fn run_updater(debug_mode: bool) {
eprintln!("[错误] WebSocket: {}", error);
});
// 设置首次连接回调 - 发送 GetFileVer 命令
let debug_for_first = debug_mode;
let device_number = resolve_device_number();
client.on_first_connect(move |_url, sender| {
let device_number = device_number.clone();
// 设置首次连接回调GetFileVer 改到收到 welcome 后发送)
let debug_first = debug_mode;
let device_number_first = resolve_device_number();
client.on_first_connect(move |_url, _sender| {
let device_number = device_number_first.clone();
Box::pin(async move {
// 仅当有有效的 DeviceNumber 时才发送 GetFileVer 命令
let ts = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
if device_number.is_empty() || device_number == "UNKNOWN" {
if debug_for_first {
println!("[首次连接] 未配置设备号,仅维持心跳连接");
if debug_first {
println!("{} [连接] 已连接,未配置设备号,仅维持心跳", ts);
}
} else {
if debug_first {
println!("{} [连接] 已连接,等待服务器欢迎消息...", ts);
}
return;
}
if debug_for_first {
println!("[首次连接] 发送 GetFileVer 命令...");
}
// 构造 GetFileVer 消息 - Type在前DeviceNumber 放在 Data 内部
// 注意:手动拼接字符串确保 Type 在 JSON 的第一位serde_json::json! 会按字母排序)
let msg_str = format!(
r#"{{"Type":"GetFileVer","Data":{{"DeviceNumber":"{}","file_list":["BootLoader.exe"]}}}}"#,
device_number
);
if debug_for_first {
println!("[首次连接] GetFileVer 已发送: {}", msg_str);
}
// 通过 sender 发送消息 (使用 .lock().await)
let sender_guard = sender.lock().await;
if let Some(ref tx) = *sender_guard {
let _ = tx.try_send(cube_lib::websocket::OutgoingMessage::Text(msg_str));
}
}) as Pin<Box<dyn std::future::Future<Output = ()> + Send + Sync>>
});
// 设置重连回调 - 在每次重连前重新加载配置
let debug_for_reconnect = debug_mode;
// 设置重连回调
let debug_reconnect = debug_mode;
client.on_reconnecting(move |attempt, url_arc| {
Box::pin(async move {
if debug_for_reconnect {
println!("[重连] 第 {} 次重连中...", attempt);
if debug_reconnect {
let ts = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
println!("{} [重连] 第 {} 次重连中...", ts, attempt);
}
// 重新读取配置文件并更新 URL
let new_url = resolve_ws_url();
// 更新 CubeLib 内部的 URL (使用 .lock().await)
*url_arc.lock().await = new_url.clone();
if debug_for_reconnect {
println!("[配置] 已重新加载,服务器地址: {}", new_url);
if debug_reconnect {
let ts = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
println!("{} [重连] 配置已更新,服务器: {}", ts, new_url);
}
}) as Pin<Box<dyn std::future::Future<Output = ()> + Send + Sync>>
});
// 设置重连成功回调 - 每次重连成功后也发送 GetFileVer
let debug_for_reconnected = debug_mode;
let device_number = resolve_device_number();
client.on_reconnected(move |_url, sender| {
let device_number = device_number.clone();
// 设置重连成功回调
let debug_reconnected = debug_mode;
let device_number_reconn = resolve_device_number();
client.on_reconnected(move |_url, _sender| {
let device_number = device_number_reconn.clone();
Box::pin(async move {
// 仅当有有效的 DeviceNumber 时才发送 GetFileVer 命令
let ts = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
if device_number.is_empty() || device_number == "UNKNOWN" {
if debug_for_reconnected {
println!("[重连成功] 未配置设备号,仅维持心跳连接");
if debug_reconnected {
println!("{} [重连] 已重连,未配置设备号", ts);
}
} else {
if debug_reconnected {
println!("{} [重连] 已重连,等待服务器欢迎消息...", ts);
}
return;
}
if debug_for_reconnected {
println!("[重连成功] 发送 GetFileVer 命令...");
}
// 构造 GetFileVer 消息 - Type在前DeviceNumber 放在 Data 内部
let msg_str = format!(
r#"{{"Type":"GetFileVer","Data":{{"DeviceNumber":"{}","file_list":["BootLoader.exe"]}}}}"#,
device_number
);
if debug_for_reconnected {
println!("[重连成功] GetFileVer 已发送: {}", msg_str);
}
// 通过 sender 发送消息
let sender_guard = sender.lock().await;
if let Some(ref tx) = *sender_guard {
let _ = tx.try_send(cube_lib::websocket::OutgoingMessage::Text(msg_str));
}
}) as Pin<Box<dyn std::future::Future<Output = ()> + Send + Sync>>
});
@@ -281,15 +273,9 @@ async fn run_updater(debug_mode: bool) {
if debug_mode {
println!("[启动] 开始连接...");
}
// connect() 会等待 websocket_loop 完全结束(包括所有重连)
client.connect().await;
if debug_mode {
println!("[启动] 连接已结束");
}
if debug_mode {
println!("Updater 已停止");
}
}