mirror of
https://github.com/clash-verge-rev/clash-verge-rev
synced 2025-05-05 07:13:44 +08:00
refactor: use of Mihomo API with socket-based communication
This commit is contained in:
parent
2fa90ef29e
commit
a58020fb52
@ -18,6 +18,9 @@
|
||||
- 外部控制的开关
|
||||
- 使用 socks 进行内核通信,以解决各种潜在的内核通信异常
|
||||
|
||||
#### 重构了:
|
||||
- Mihomo 内核不再使用 http 交互,而是使用 socket 进行通信
|
||||
|
||||
|
||||
## v2.2.3
|
||||
|
||||
|
53
src-tauri/Cargo.lock
generated
53
src-tauri/Cargo.lock
generated
@ -1824,6 +1824,12 @@ dependencies = [
|
||||
"litrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dotenv"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
@ -2913,7 +2919,7 @@ dependencies = [
|
||||
"httpdate",
|
||||
"itoa 1.0.15",
|
||||
"pin-project-lite",
|
||||
"socket2 0.5.8",
|
||||
"socket2 0.4.10",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
@ -2933,6 +2939,7 @@ dependencies = [
|
||||
"http 1.3.1",
|
||||
"http-body 1.0.1",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa 1.0.15",
|
||||
"pin-project-lite",
|
||||
"smallvec",
|
||||
@ -2988,9 +2995,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.10"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
|
||||
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
@ -2998,13 +3005,29 @@ dependencies = [
|
||||
"http 1.3.1",
|
||||
"http-body 1.0.1",
|
||||
"hyper 1.6.0",
|
||||
"libc",
|
||||
"pin-project-lite",
|
||||
"socket2 0.5.8",
|
||||
"socket2 0.5.9",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyperlocal"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"http-body-util",
|
||||
"hyper 1.6.0",
|
||||
"hyper-util",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.62"
|
||||
@ -3852,10 +3875,18 @@ dependencies = [
|
||||
name = "mihomo_api"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"async-trait",
|
||||
"dotenv",
|
||||
"futures",
|
||||
"http-body-util",
|
||||
"hyper 1.6.0",
|
||||
"hyper-util",
|
||||
"hyperlocal",
|
||||
"lazy_static",
|
||||
"serde_json",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5344,7 +5375,7 @@ dependencies = [
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"socket2 0.5.8",
|
||||
"socket2 0.5.9",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@ -5380,7 +5411,7 @@ dependencies = [
|
||||
"cfg_aliases 0.2.1",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2 0.5.8",
|
||||
"socket2 0.5.9",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
@ -6484,9 +6515,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.8"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
|
||||
checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
@ -7484,7 +7515,7 @@ dependencies = [
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2 0.5.8",
|
||||
"socket2 0.5.9",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
|
@ -2,6 +2,7 @@ use super::CmdResult;
|
||||
use crate::{
|
||||
config::*, core::*, feat, module::mihomo::MihomoManager, process::AsyncHandler, wrap_err,
|
||||
};
|
||||
use mihomo_api::model::MihomoClient;
|
||||
use serde_yaml::Mapping;
|
||||
|
||||
/// 复制Clash环境变量
|
||||
@ -70,6 +71,7 @@ pub async fn clash_api_get_proxy_delay(
|
||||
MihomoManager::global()
|
||||
.test_proxy_delay(&name, url, timeout)
|
||||
.await
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// 测试URL延迟
|
||||
|
@ -1,24 +1,23 @@
|
||||
use mihomo_api::model::MihomoClient;
|
||||
|
||||
use super::CmdResult;
|
||||
use crate::module::mihomo::MihomoManager;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_proxies() -> CmdResult<serde_json::Value> {
|
||||
let mannager = MihomoManager::global();
|
||||
|
||||
mannager
|
||||
.refresh_proxies()
|
||||
.await
|
||||
.map(|_| mannager.get_proxies())
|
||||
.or_else(|_| Ok(mannager.get_proxies()))
|
||||
let manager = MihomoManager::global();
|
||||
manager.refresh_proxies().await.map_err(|e| e.to_string())?;
|
||||
let data = manager.get_data_proxies().await;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_providers_proxies() -> CmdResult<serde_json::Value> {
|
||||
let mannager = MihomoManager::global();
|
||||
|
||||
mannager
|
||||
let manager = MihomoManager::global();
|
||||
manager
|
||||
.refresh_providers_proxies()
|
||||
.await
|
||||
.map(|_| mannager.get_providers_proxies())
|
||||
.or_else(|_| Ok(mannager.get_providers_proxies()))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let data = manager.get_data_providers_proxies().await;
|
||||
Ok(data)
|
||||
}
|
||||
|
@ -51,6 +51,10 @@ impl IClashTemp {
|
||||
map.insert("ipv6".into(), true.into());
|
||||
map.insert("mode".into(), "rule".into());
|
||||
map.insert("external-controller".into(), "127.0.0.1:9097".into());
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
map.insert("external-controller-unix".into(), "mihomo.sock".into());
|
||||
#[cfg(target_os = "windows")]
|
||||
map.insert("external-controller-pipe".into(), r"\\.\pipe\mihomo".into());
|
||||
let mut cors_map = Mapping::new();
|
||||
cors_map.insert("allow-private-network".into(), true.into());
|
||||
cors_map.insert("allow-origins".into(), vec!["*"].into());
|
||||
|
@ -15,6 +15,7 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use anyhow::Result;
|
||||
use mihomo_api::model::MihomoClient;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::{fmt, path::PathBuf, sync::Arc};
|
||||
use tauri_plugin_shell::{process::CommandChild, ShellExt};
|
||||
|
@ -6,6 +6,7 @@ use crate::{
|
||||
process::AsyncHandler,
|
||||
utils::{logging::Type, resolve},
|
||||
};
|
||||
use mihomo_api::model::MihomoClient;
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use tauri::Manager;
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
use mihomo_api::model::MihomoClient;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::AppHandleManager;
|
||||
use crate::{
|
||||
@ -74,12 +76,11 @@ pub fn quit() {
|
||||
"enable": false
|
||||
}
|
||||
});
|
||||
timeout(
|
||||
Duration::from_secs(1),
|
||||
MihomoManager::global().patch_configs(disable_tun),
|
||||
)
|
||||
.await
|
||||
.is_ok()
|
||||
|
||||
let patch_future =
|
||||
async { MihomoManager::global().patch_configs(disable_tun).await };
|
||||
|
||||
timeout(Duration::from_secs(1), patch_future).await.is_ok()
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::config::Config;
|
||||
use crate::{config::Config, utils::dirs::app_socket_path};
|
||||
use mihomo_api;
|
||||
use once_cell::sync::{Lazy, OnceCell};
|
||||
use std::sync::Mutex;
|
||||
@ -24,20 +24,18 @@ impl MihomoManager {
|
||||
&INSTANCE
|
||||
}
|
||||
|
||||
pub fn global() -> mihomo_api::MihomoManager {
|
||||
pub fn global() -> &'static mihomo_api::MihomoManager {
|
||||
let instance = MihomoManager::__global();
|
||||
let (current_server, headers) = MihomoManager::get_clash_client_info().unwrap();
|
||||
|
||||
let lock = instance.mihomo.lock().unwrap();
|
||||
if let Some(mihomo) = lock.get() {
|
||||
if mihomo.get_mihomo_server() == current_server {
|
||||
return mihomo.clone();
|
||||
}
|
||||
let mihomo = &instance.mihomo;
|
||||
let lock = mihomo.lock().unwrap();
|
||||
|
||||
if lock.get().is_none() {
|
||||
let socket_path = MihomoManager::get_socket_path();
|
||||
lock.set(mihomo_api::MihomoManager::new(socket_path)).ok();
|
||||
}
|
||||
|
||||
lock.set(mihomo_api::MihomoManager::new(current_server, headers))
|
||||
.ok();
|
||||
lock.get().unwrap().clone()
|
||||
unsafe { std::mem::transmute(lock.get().unwrap()) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,4 +65,12 @@ impl MihomoManager {
|
||||
let token = http::header::HeaderValue::from_str(&auth).unwrap();
|
||||
(ws_url, token)
|
||||
}
|
||||
|
||||
fn get_socket_path() -> String {
|
||||
#[cfg(unix)]
|
||||
let socket_path = app_socket_path().unwrap();
|
||||
#[cfg(windows)]
|
||||
let socket_path = r"\\.\pipe\mihomo";
|
||||
socket_path
|
||||
}
|
||||
}
|
||||
|
@ -179,3 +179,10 @@ pub fn get_encryption_key() -> Result<Vec<u8>> {
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn app_socket_path() -> Result<String> {
|
||||
let app_dir = app_home_dir()?;
|
||||
let socket_path = app_dir.join("mihomo.sock");
|
||||
let socket_path = path_to_str(&socket_path)?;
|
||||
Ok(socket_path.to_string())
|
||||
}
|
||||
|
@ -15,8 +15,7 @@ use parking_lot::RwLock;
|
||||
use percent_encoding::percent_decode_str;
|
||||
use serde_json;
|
||||
use serde_yaml::Mapping;
|
||||
use std::net::TcpListener;
|
||||
use std::sync::Arc;
|
||||
use std::{net::TcpListener, sync::Arc};
|
||||
use tauri::{App, Manager};
|
||||
|
||||
use tauri::Url;
|
||||
|
@ -1,13 +0,0 @@
|
||||
$pipeName = "\\.\pipe\mihomo"
|
||||
$pipe = new-object System.IO.Pipes.NamedPipeClientStream(".", "mihomo", [System.IO.Pipes.PipeDirection]::InOut)
|
||||
$pipe.Connect(1000) # 尝试连接 1 秒
|
||||
if ($pipe.IsConnected) {
|
||||
Write-Host "成功连接到管道"
|
||||
# 示例写入或读取可以加上如下内容
|
||||
# $writer = new-object System.IO.StreamWriter($pipe)
|
||||
# $writer.WriteLine("hello pipe")
|
||||
# $writer.Flush()
|
||||
$pipe.Close()
|
||||
} else {
|
||||
Write-Host "连接失败"
|
||||
}
|
@ -42,8 +42,7 @@
|
||||
// }
|
||||
|
||||
pub mod model;
|
||||
pub use model::E;
|
||||
pub use model::MihomoData;
|
||||
pub use model::MihomoManager;
|
||||
pub use model::{E, MihomoData, MihomoManager};
|
||||
pub mod platform;
|
||||
pub mod sock;
|
||||
pub mod platform;
|
||||
pub use platform::Client;
|
||||
|
@ -40,7 +40,7 @@ pub trait MihomoClient: Sized {
|
||||
async fn refresh_proxies(&self) -> Result<&Self, E>;
|
||||
async fn refresh_providers_proxies(&self) -> Result<&Self, E>;
|
||||
async fn get_connections(&self) -> Result<Value, E>;
|
||||
async fn delete_connections(&self, id: &str) -> Result<(), E>;
|
||||
async fn delete_connection(&self, id: &str) -> Result<(), E>;
|
||||
async fn test_proxy_delay(
|
||||
&self,
|
||||
name: &str,
|
||||
|
@ -1,10 +1,9 @@
|
||||
use crate::model::E;
|
||||
use crate::{model::E, platform::Client};
|
||||
use async_trait::async_trait;
|
||||
use hyper::Method;
|
||||
use serde_json::Value;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::platform::Client;
|
||||
|
||||
use crate::{
|
||||
MihomoData,
|
||||
@ -47,7 +46,9 @@ impl MihomoClient for MihomoManager {
|
||||
body: Option<Value>,
|
||||
) -> Result<Value, E> {
|
||||
let client = self.client.lock().await;
|
||||
client.send_request(self.socket_path.clone(), path, method, body).await
|
||||
client
|
||||
.send_request(self.socket_path.clone(), path, method, body)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_version(&self) -> Result<Value, E> {
|
||||
@ -96,7 +97,7 @@ impl MihomoClient for MihomoManager {
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
async fn delete_connections(&self, id: &str) -> Result<(), E> {
|
||||
async fn delete_connection(&self, id: &str) -> Result<(), E> {
|
||||
let _ = self
|
||||
.send_request(&format!("/connections/{}", id), Method::DELETE, None)
|
||||
.await?;
|
||||
|
Loading…
x
Reference in New Issue
Block a user