| | |
| | | mod tokio_utils; |
| | | mod pipe_server; |
| | | mod ws_client; |
| | | use crate::ws_client::LATEST_WS_DATA; |
| | | mod serial_port; |
| | | |
| | | |
| | | |
| | | use std::sync::Mutex; |
| | | use tauri::async_runtime::spawn; |
| | | use tokio::io::{AsyncReadExt, AsyncWriteExt}; |
| | | use tauri::Manager; |
| | | use tokio_utils::{set_complete,setup,SetupState}; |
| | | use std::fs::OpenOptions; |
| | | use std::io::Write; |
| | | use chrono::Local; |
| | | |
| | | |
| | | // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ |
| | | use crate::pipe_server::start_pipe_server; |
| | | |
| | | #[tauri::command] |
| | | fn get_latest_ws_data() -> Option<String> { |
| | | LATEST_WS_DATA.lock().unwrap().clone() |
| | | } |
| | | |
| | | |
| | | #[tauri::command] |
| | | fn greet(name: &str) -> String { |
| | | format!("Hello, {}! You've been greeted from Rust!", name) |
| | | } |
| | | |
| | | #[tauri::command] |
| | | async fn start_pipe_server_command(pipe_name: String) -> Result<(), String> { |
| | | start_pipe_server(&pipe_name) |
| | | .await |
| | | .map_err(|e| e.to_string()) |
| | | fn log_data(app_handle: tauri::AppHandle, data: String) -> Result<(), String> { |
| | | let app_data_path = app_handle.path().app_data_dir() |
| | | .or_else(|_| Err("Could not get app data directory".to_string()))?; |
| | | |
| | | let log_dir = app_data_path.join("logs"); |
| | | if !log_dir.exists() { |
| | | std::fs::create_dir_all(&log_dir) |
| | | .map_err(|e| format!("Failed to create log directory: {}", e))?; |
| | | } |
| | | |
| | | let current_date = Local::now().format("%Y-%m-%d").to_string(); |
| | | let log_file_path = log_dir.join(format!("log_{}.txt", current_date)); |
| | | |
| | | println!("log_file_path: {:?}", log_file_path); |
| | | let mut file = OpenOptions::new() |
| | | .create(true) |
| | | .append(true) |
| | | .open(&log_file_path) |
| | | .map_err(|e| format!("Failed to open log file: {}", e))?; |
| | | |
| | | let timestamp = Local::now().format("[%Y-%m-%d %H:%M:%S]").to_string(); |
| | | writeln!(file, "{} {}", timestamp, data) |
| | | .map_err(|e| format!("Failed to write to log file: {}", e))?; |
| | | |
| | | Ok(()) |
| | | } |
| | | |
| | | #[tauri::command] |
| | | async fn send_pipe_message(pipe_name: String, message: String) -> Result<String, String> { |
| | | let pipe_path: String = format!(r"\\.\pipe\{}", pipe_name); |
| | | |
| | | let mut client = tokio::net::windows::named_pipe::ClientOptions::new() |
| | | .open(&pipe_path) |
| | | .map_err(|e| e.to_string())?; |
| | | |
| | | client.write_all(message.as_bytes()).await.map_err(|e| e.to_string())?; |
| | | |
| | | let mut buf = [0u8; 1024]; |
| | | let n = client.read(&mut buf).await.map_err(|e| e.to_string())?; |
| | | |
| | | String::from_utf8(buf[..n].to_vec()) |
| | | .map_err(|e| e.to_string()) |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | backend_task: false, |
| | | })) |
| | | // Add a command we can use to check |
| | | .invoke_handler(tauri::generate_handler![greet, set_complete, start_pipe_server_command, send_pipe_message, get_latest_ws_data]) |
| | | .invoke_handler(tauri::generate_handler![ |
| | | greet, |
| | | set_complete, |
| | | serial_port::open_serial_port, |
| | | serial_port::close_serial_port, |
| | | serial_port::write_serial_data, |
| | | serial_port::list_serial_ports, |
| | | log_data |
| | | ]) |
| | | // Use the setup hook to execute setup related tasks |
| | | // Runs before the main loop, so no windows are yet created |
| | | .setup(|app| { |
| | | // 启动 WebSocket 客户端(异步任务) |
| | | ws_client::start_ws_client(); |
| | | // Spawn setup as a non-blocking task so the windows can be |
| | | // created and ran while it executes |
| | | spawn(setup(app.handle().clone())); |