desktop counter
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
// src-tauri/src/plugins/vpn-plugin/build.rs
|
||||
|
||||
const COMMANDS: &[&str] = &[
|
||||
"start_vpn",
|
||||
"stop_vpn",
|
||||
|
||||
@@ -1,33 +1,45 @@
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Arc, Mutex}; // Добавили Arc
|
||||
|
||||
use crate::models::*;
|
||||
use crate::VpnInterface;
|
||||
use netrunner_client::Session;
|
||||
use netrunner_client::SessionManager;
|
||||
use serde::de::DeserializeOwned;
|
||||
// ВАЖНО: Добавляем Emitter для возможности вызова .emit()
|
||||
use tauri::Manager; // Важно для app.manage()
|
||||
use tauri::{plugin::PluginApi, AppHandle, Emitter, Runtime};
|
||||
|
||||
pub fn init<R: Runtime, C: DeserializeOwned>(
|
||||
app: &AppHandle<R>,
|
||||
_api: PluginApi<R, C>,
|
||||
) -> crate::Result<Vpn<R>> {
|
||||
Ok(Vpn {
|
||||
let vpn = Vpn {
|
||||
app: app.clone(),
|
||||
active_session: Mutex::new(None),
|
||||
})
|
||||
// Оборачиваем Mutex в Arc, чтобы структуру Vpn можно было клонировать и шарить
|
||||
active_session: Arc::new(Mutex::new(None)),
|
||||
};
|
||||
|
||||
// 🛑 САМОЕ ВАЖНОЕ: Регистрируем стейт в Tauri, чтобы app.state() больше не падал!
|
||||
app.manage(vpn.clone());
|
||||
|
||||
Ok(vpn)
|
||||
}
|
||||
|
||||
pub struct Vpn<R: Runtime> {
|
||||
app: AppHandle<R>,
|
||||
active_session: Mutex<Option<Arc<Session>>>,
|
||||
active_session: Arc<Mutex<Option<Arc<Session>>>>,
|
||||
}
|
||||
|
||||
impl<R: Runtime> Clone for Vpn<R> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
app: self.app.clone(),
|
||||
active_session: self.active_session.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Runtime> VpnInterface<R> for Vpn<R> {
|
||||
fn start_vpn(&self, _config: TunnelConfig, ip: String, port: i32) -> crate::Result<()> {
|
||||
// 1. Сразу уведомляем фронт о начале подключения
|
||||
// Имя события совпадает с тем, что мы слушаем в useEffect
|
||||
let _ = self.app.emit(
|
||||
"status-change",
|
||||
StatusResponse {
|
||||
@@ -35,14 +47,16 @@ impl<R: Runtime> VpnInterface<R> for Vpn<R> {
|
||||
},
|
||||
);
|
||||
|
||||
// Запуск сессии (здесь может быть паника, если нет прав админа!)
|
||||
let session = SessionManager.spawn_session(format!("{}:{}", ip, port), None, ".".into());
|
||||
// Обрати внимание: SessionManager.spawn_session -> SessionManager::new().spawn_session
|
||||
let session =
|
||||
SessionManager::new().spawn_session(format!("{}:{}", ip, port), None, ".".into());
|
||||
|
||||
// Сохраняем сессию
|
||||
let mut lock = self.active_session.lock().unwrap();
|
||||
*lock = Some(session);
|
||||
{
|
||||
let mut lock = self.active_session.lock().unwrap();
|
||||
*lock = Some(session);
|
||||
}
|
||||
|
||||
// 2. Успешное подключение
|
||||
let _ = self.app.emit(
|
||||
"status-change",
|
||||
StatusResponse {
|
||||
@@ -50,6 +64,38 @@ impl<R: Runtime> VpnInterface<R> for Vpn<R> {
|
||||
},
|
||||
);
|
||||
|
||||
// --- ФОНОВЫЙ ЦИКЛ СТАТИСТИКИ (Оптимизированный) ---
|
||||
let app_handle = self.app.clone();
|
||||
|
||||
// Клонируем умный указатель (Arc), чтобы отдать его внутрь потока
|
||||
let session_ref = self.active_session.clone();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
|
||||
// Теперь мы НЕ обращаемся к app_handle.state(), а проверяем локальную ссылку!
|
||||
// Это полностью исключает дедлоки стейта Tauri.
|
||||
if session_ref.lock().unwrap().is_none() {
|
||||
eprintln!("--- [DEBUG] VPN Session ended. Stopping desktop stats loop. ---");
|
||||
break;
|
||||
}
|
||||
|
||||
let stats = SessionManager::new().get_traffic_stats();
|
||||
|
||||
let _ = app_handle.emit(
|
||||
"traffic-stats",
|
||||
TrafficStatsResponse {
|
||||
rx_bytes: stats.rx_bytes,
|
||||
tx_bytes: stats.tx_bytes,
|
||||
rx_packets: stats.rx_packets,
|
||||
tx_packets: stats.tx_packets,
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -58,7 +104,6 @@ impl<R: Runtime> VpnInterface<R> for Vpn<R> {
|
||||
if let Some(session) = lock.take() {
|
||||
session.stop();
|
||||
|
||||
// 3. Уведомляем об отключении
|
||||
let _ = self.app.emit(
|
||||
"status-change",
|
||||
StatusResponse {
|
||||
|
||||
Reference in New Issue
Block a user