From a6bd104635c8e7e292ee9247b2f2531332cb2453 Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 8 Apr 2026 10:52:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B6=E5=88=B0=20welcome=20=E5=90=8E?= =?UTF-8?q?=E6=89=8D=E5=8F=91=20GetFileVer=20=E2=9C=85=202.=20=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=A0=BC=E5=BC=8F=E7=BB=9F=E4=B8=80=E4=B8=BA=20yyyy-M?= =?UTF-8?q?M-dd=20HH:mm:ss.fff=20=E6=94=B6=E5=88=B0/=E5=8F=91=E9=80=81?= =?UTF-8?q?=E6=B6=88=E6=81=AF=EF=BC=9Ajson?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Updater/Cargo.lock | 129 +++++++++++++++++ Windows/CS/Framework4.0/Updater/Cargo.toml | 1 + Windows/CS/Framework4.0/Updater/src/main.rs | 152 +++++++++----------- 3 files changed, 199 insertions(+), 83 deletions(-) diff --git a/Windows/CS/Framework4.0/Updater/Cargo.lock b/Windows/CS/Framework4.0/Updater/Cargo.lock index d414191..8c0cd42 100644 --- a/Windows/CS/Framework4.0/Updater/Cargo.lock +++ b/Windows/CS/Framework4.0/Updater/Cargo.lock @@ -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" diff --git a/Windows/CS/Framework4.0/Updater/Cargo.toml b/Windows/CS/Framework4.0/Updater/Cargo.toml index b703de5..d479d1b 100644 --- a/Windows/CS/Framework4.0/Updater/Cargo.toml +++ b/Windows/CS/Framework4.0/Updater/Cargo.toml @@ -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" } diff --git a/Windows/CS/Framework4.0/Updater/src/main.rs b/Windows/CS/Framework4.0/Updater/src/main.rs index 23720f3..ef4d623 100644 --- a/Windows/CS/Framework4.0/Updater/src/main.rs +++ b/Windows/CS/Framework4.0/Updater/src/main.rs @@ -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 + 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 + 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 + 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 已停止"); } }