mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 08:45:41 +08:00
refactor: core logic
This commit is contained in:
@@ -5,27 +5,24 @@ use crate::utils::dirs;
|
|||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use serde_yaml::Mapping;
|
use serde_yaml::Mapping;
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use sysinfo::ProcessesToUpdate;
|
use tauri_plugin_shell::process::{CommandChild, CommandEvent};
|
||||||
use sysinfo::{ProcessRefreshKind, RefreshKind, System};
|
|
||||||
use tauri_plugin_shell::process::CommandEvent;
|
|
||||||
use tauri_plugin_shell::ShellExt;
|
use tauri_plugin_shell::ShellExt;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CoreManager {
|
pub struct CoreManager {
|
||||||
running: Arc<Mutex<bool>>,
|
running: Arc<Mutex<bool>>,
|
||||||
|
sidecar: Arc<Mutex<Option<CommandChild>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CoreManager {
|
impl CoreManager {
|
||||||
pub fn global() -> &'static CoreManager {
|
pub fn global() -> &'static CoreManager {
|
||||||
static CORE_MANAGER: OnceCell<CoreManager> = OnceCell::new();
|
static CORE_MANAGER: OnceCell<CoreManager> = OnceCell::new();
|
||||||
|
|
||||||
CORE_MANAGER.get_or_init(|| CoreManager {
|
CORE_MANAGER.get_or_init(|| CoreManager {
|
||||||
running: Arc::new(Mutex::new(false)),
|
running: Arc::new(Mutex::new(false)),
|
||||||
|
sidecar: Arc::new(Mutex::new(None)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +76,6 @@ impl CoreManager {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let clash_core = { Config::verge().latest().clash_core.clone() };
|
|
||||||
let clash_core = clash_core.unwrap_or("verge-mihomo".into());
|
|
||||||
// 关闭tun模式
|
// 关闭tun模式
|
||||||
let mut disable = Mapping::new();
|
let mut disable = Mapping::new();
|
||||||
let mut tun = Mapping::new();
|
let mut tun = Mapping::new();
|
||||||
@@ -89,11 +84,15 @@ impl CoreManager {
|
|||||||
log::debug!(target: "app", "disable tun mode");
|
log::debug!(target: "app", "disable tun mode");
|
||||||
log_err!(clash_api::patch_configs(&disable).await);
|
log_err!(clash_api::patch_configs(&disable).await);
|
||||||
|
|
||||||
// 服务模式
|
if let Some(sidecar) = self.sidecar.lock().await.take() {
|
||||||
log::debug!(target: "app", "stop the core by service");
|
let _ = sidecar.kill();
|
||||||
log_err!(service::stop_core_by_service().await);
|
} else {
|
||||||
|
// 服务模式
|
||||||
kill_processes_by_name(clash_core.as_str());
|
if service::check_service().await.is_ok() {
|
||||||
|
log::debug!(target: "app", "stop the core by service");
|
||||||
|
log_err!(service::stop_core_by_service().await);
|
||||||
|
}
|
||||||
|
}
|
||||||
*running = false;
|
*running = false;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -113,25 +112,17 @@ impl CoreManager {
|
|||||||
// 服务模式
|
// 服务模式
|
||||||
let service_enable = { Config::verge().latest().enable_service_mode };
|
let service_enable = { Config::verge().latest().enable_service_mode };
|
||||||
let service_enable = service_enable.unwrap_or(false);
|
let service_enable = service_enable.unwrap_or(false);
|
||||||
if service_enable {
|
|
||||||
// 服务模式启动失败就直接运行sidecar
|
|
||||||
log::debug!(target: "app", "try to run core in service mode");
|
|
||||||
|
|
||||||
let res = async {
|
if service::check_service().await.is_ok() {
|
||||||
service::check_service().await?;
|
log::debug!(target: "app", "try to run core in service mode");
|
||||||
service::run_core_by_service(&config_path).await
|
if service_enable {
|
||||||
}
|
service::run_core_by_service(&config_path).await?;
|
||||||
.await;
|
let mut sidecar = self.sidecar.lock().await;
|
||||||
match res {
|
if sidecar.is_some() {
|
||||||
Ok(_) => {
|
sidecar.take();
|
||||||
return {
|
|
||||||
*running = true;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
log::error!(target: "app start service err", "{err}");
|
|
||||||
}
|
}
|
||||||
|
*running = true;
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +132,10 @@ impl CoreManager {
|
|||||||
let args = vec!["-d", app_dir, "-f", config_path];
|
let args = vec!["-d", app_dir, "-f", config_path];
|
||||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||||
let cmd = app_handle.shell().sidecar(clash_core)?;
|
let cmd = app_handle.shell().sidecar(clash_core)?;
|
||||||
let (mut rx, _) = cmd.args(args).spawn()?;
|
let (mut rx, cmd_child) = cmd.args(args).spawn()?;
|
||||||
|
let mut sidecar = self.sidecar.lock().await;
|
||||||
|
|
||||||
|
*sidecar = Some(cmd_child);
|
||||||
|
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
while let Some(event) = rx.recv().await {
|
while let Some(event) = rx.recv().await {
|
||||||
@@ -247,17 +241,3 @@ impl CoreManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kill_processes_by_name(process_name: &str) {
|
|
||||||
let mut system = System::new_with_specifics(
|
|
||||||
RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
|
|
||||||
);
|
|
||||||
|
|
||||||
system.refresh_processes(ProcessesToUpdate::All);
|
|
||||||
let process_name = OsStr::new(process_name);
|
|
||||||
let procs = system.processes_by_name(process_name);
|
|
||||||
for proc in procs {
|
|
||||||
log::debug!(target: "app", "Killing process: {:?}", proc.name());
|
|
||||||
proc.kill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,9 +4,8 @@ use anyhow::{bail, Context, Result};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
|
||||||
use std::{env::current_exe, process::Command as StdCommand};
|
use std::{env::current_exe, process::Command as StdCommand};
|
||||||
use tokio::time::sleep;
|
use tokio::time::Duration;
|
||||||
|
|
||||||
// Windows only
|
// Windows only
|
||||||
|
|
||||||
@@ -268,6 +267,7 @@ pub async fn check_service() -> Result<JsonResponse> {
|
|||||||
let url = format!("{SERVICE_URL}/get_clash");
|
let url = format!("{SERVICE_URL}/get_clash");
|
||||||
let response = reqwest::ClientBuilder::new()
|
let response = reqwest::ClientBuilder::new()
|
||||||
.no_proxy()
|
.no_proxy()
|
||||||
|
.timeout(Duration::from_secs(3))
|
||||||
.build()?
|
.build()?
|
||||||
.get(url)
|
.get(url)
|
||||||
.send()
|
.send()
|
||||||
@@ -282,13 +282,6 @@ pub async fn check_service() -> Result<JsonResponse> {
|
|||||||
|
|
||||||
/// start the clash by service
|
/// start the clash by service
|
||||||
pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
|
pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
|
||||||
let status = check_service().await?;
|
|
||||||
|
|
||||||
if status.code == 0 {
|
|
||||||
stop_core_by_service().await?;
|
|
||||||
sleep(Duration::from_secs(1)).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
let clash_core = { Config::verge().latest().clash_core.clone() };
|
let clash_core = { Config::verge().latest().clash_core.clone() };
|
||||||
let clash_core = clash_core.unwrap_or("verge-mihomo".into());
|
let clash_core = clash_core.unwrap_or("verge-mihomo".into());
|
||||||
|
|
||||||
@@ -313,40 +306,28 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
|
|||||||
map.insert("log_file", log_path);
|
map.insert("log_file", log_path);
|
||||||
|
|
||||||
let url = format!("{SERVICE_URL}/start_clash");
|
let url = format!("{SERVICE_URL}/start_clash");
|
||||||
let res = reqwest::ClientBuilder::new()
|
let _ = reqwest::ClientBuilder::new()
|
||||||
.no_proxy()
|
.no_proxy()
|
||||||
.build()?
|
.build()?
|
||||||
.post(url)
|
.post(url)
|
||||||
.json(&map)
|
.json(&map)
|
||||||
.send()
|
.send()
|
||||||
.await?
|
|
||||||
.json::<JsonResponse>()
|
|
||||||
.await
|
.await
|
||||||
.context("failed to connect to the Clash Verge Service")?;
|
.context("failed to connect to the Clash Verge Service")?;
|
||||||
|
|
||||||
if res.code != 0 {
|
|
||||||
bail!(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// stop the clash by service
|
/// stop the clash by service
|
||||||
pub(super) async fn stop_core_by_service() -> Result<()> {
|
pub(super) async fn stop_core_by_service() -> Result<()> {
|
||||||
let url = format!("{SERVICE_URL}/stop_clash");
|
let url = format!("{SERVICE_URL}/stop_clash");
|
||||||
let res = reqwest::ClientBuilder::new()
|
let _ = reqwest::ClientBuilder::new()
|
||||||
.no_proxy()
|
.no_proxy()
|
||||||
.build()?
|
.build()?
|
||||||
.post(url)
|
.post(url)
|
||||||
.send()
|
.send()
|
||||||
.await?
|
|
||||||
.json::<JsonResponse>()
|
|
||||||
.await
|
.await
|
||||||
.context("failed to connect to the Clash Verge Service")?;
|
.context("failed to connect to the Clash Verge Service")?;
|
||||||
|
|
||||||
if res.code != 0 {
|
|
||||||
bail!(res.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user