From 34725b517b249b3b341fe02459457f77ca24df1d Mon Sep 17 00:00:00 2001 From: GyDi Date: Thu, 23 Dec 2021 01:35:17 +0800 Subject: [PATCH] feat: implement a simple singleton process --- src-tauri/Cargo.lock | 232 ++++++++++++++++++++++++++++++++++ src-tauri/Cargo.toml | 2 + src-tauri/src/main.rs | 14 +- src-tauri/src/utils/mod.rs | 1 + src-tauri/src/utils/server.rs | 38 ++++++ 5 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 src-tauri/src/utils/server.rs diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 612eaf9..786edd5 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -46,6 +46,7 @@ dependencies = [ "dirs 4.0.0", "log", "log4rs", + "port_scanner", "reqwest", "serde", "serde_json", @@ -53,6 +54,7 @@ dependencies = [ "tauri", "tauri-build", "tokio", + "warp", "winreg 0.10.1", ] @@ -200,6 +202,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "bstr" version = "0.2.17" @@ -209,6 +220,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "buf_redux" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" +dependencies = [ + "memchr", + "safemem", +] + [[package]] name = "bumpalo" version = "3.8.0" @@ -502,6 +523,15 @@ dependencies = [ "objc", ] +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.3.0" @@ -1304,6 +1334,31 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +[[package]] +name = "headers" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c4eb0471fcb85846d8b0690695ef354f9afb11cb03cac2e1d7c9253351afb0" +dependencies = [ + "base64", + "bitflags", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha-1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + [[package]] name = "heck" version = "0.3.3" @@ -1739,6 +1794,16 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "mime_guess" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minisign-verify" version = "0.1.8" @@ -1786,6 +1851,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "multipart" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" +dependencies = [ + "buf_redux", + "httparse", + "log", + "mime", + "mime_guess", + "quick-error", + "rand 0.8.4", + "safemem", + "tempfile", + "twoway", +] + [[package]] name = "native-tls" version = "0.2.8" @@ -2005,6 +2088,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "open" version = "2.0.2" @@ -2253,6 +2342,26 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-project" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.7" @@ -2308,6 +2417,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "port_scanner" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "325a6d2ac5dee293c3b2612d4993b98aec1dff096b0a2dae70ed7d95784a05da" + [[package]] name = "ppv-lite86" version = "0.2.15" @@ -2378,6 +2493,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.10" @@ -2693,6 +2814,12 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + [[package]] name = "same-file" version = "1.0.6" @@ -2889,6 +3016,19 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer", + "cfg-if 1.0.0", + "cpufeatures", + "digest", + "opaque-debug", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -3472,6 +3612,30 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8" +dependencies = [ + "futures-util", + "log", + "pin-project", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.6.9" @@ -3508,6 +3672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if 1.0.0", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3574,6 +3739,34 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "tungstenite" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" +dependencies = [ + "base64", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand 0.8.4", + "sha-1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "twoway" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" +dependencies = [ + "memchr", +] + [[package]] name = "typemap" version = "0.3.3" @@ -3595,6 +3788,15 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.7" @@ -3716,6 +3918,36 @@ dependencies = [ "try-lock", ] +[[package]] +name = "warp" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers", + "http", + "hyper", + "log", + "mime", + "mime_guess", + "multipart", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded 0.7.0", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tokio-util", + "tower-service", + "tracing", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index e8f10ef..6b9694b 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -23,6 +23,8 @@ reqwest = { version = "0.11", features = ["json"] } tokio = { version = "1", features = ["full"] } log = "0.4.14" log4rs = "1.0.0" +warp = "0.3" +port_scanner = "0.1.5" [target.'cfg(windows)'.dependencies] winreg = { version = "0.10", features = ["transactions"] } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 96ee2f6..38f1bae 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -12,7 +12,11 @@ mod utils; use crate::{ events::state, - utils::{clash::put_clash_profile, config::read_verge}, + utils::{ + clash::put_clash_profile, + config::read_verge, + server::{check_singleton, embed_server}, + }, }; use std::sync::{Arc, Mutex}; use tauri::{ @@ -21,6 +25,11 @@ use tauri::{ }; fn main() -> std::io::Result<()> { + if check_singleton().is_err() { + println!("app exists"); + return Ok(()); + } + let sub_menu = SystemTraySubmenu::new( "出站规则", SystemTrayMenu::new() @@ -76,6 +85,9 @@ fn main() -> std::io::Result<()> { .build(tauri::generate_context!()) .expect("error while running tauri application"); + // a simple http server + embed_server(&app.handle()); + // init app config utils::init::init_app(app.package_info()); // run clash sidecar diff --git a/src-tauri/src/utils/mod.rs b/src-tauri/src/utils/mod.rs index 0430f37..9794a2c 100644 --- a/src-tauri/src/utils/mod.rs +++ b/src-tauri/src/utils/mod.rs @@ -5,4 +5,5 @@ pub mod clash; pub mod config; pub mod fetch; pub mod init; +pub mod server; pub mod sysopt; diff --git a/src-tauri/src/utils/server.rs b/src-tauri/src/utils/server.rs new file mode 100644 index 0000000..b860dd4 --- /dev/null +++ b/src-tauri/src/utils/server.rs @@ -0,0 +1,38 @@ +extern crate warp; + +use port_scanner::local_port_available; +use tauri::{AppHandle, Manager}; +use warp::Filter; + +const SERVER_PORT: u16 = 33333; + +/// check whether there is already exists +pub fn check_singleton() -> Result<(), ()> { + if !local_port_available(SERVER_PORT) { + tauri::async_runtime::block_on(async { + let url = format!("http://127.0.0.1:{}/commands/visible", SERVER_PORT); + reqwest::get(url).await.unwrap(); + Err(()) + }) + } else { + Ok(()) + } +} + +/// The embed server only be used to implement singleton process +/// maybe it can be used as pac server later +pub fn embed_server(app: &AppHandle) { + let window = app.get_window("main").unwrap(); + + let commands = warp::path!("commands" / "visible").map(move || { + window.show().unwrap(); + window.set_focus().unwrap(); + return format!("ok"); + }); + + tauri::async_runtime::spawn(async move { + warp::serve(commands) + .bind(([127, 0, 0, 1], SERVER_PORT)) + .await; + }); +}