import { ipcMain,app,BrowserWindow } from 'electron'; import { getDeviceId, getWiredConnectionName,netmaskToCidr } from '../utils/utils'; const { exec } = require('child_process'); const { promisify } = require('util'); const execAsync = promisify(exec); // 模拟grpc服务端 import { BTGrpcClient } from '../grpc/BTGrpcClient'; import { MockBTService } from '../grpc/MockBTService'; // 客户端和服务端 通信 const IS_TEST_MODE = true; // 设置为 false 时连接真实后端 const GRPC_SERVER_PORT = 50051; // 先声明变量,但不立即初始化 let btGrpcClient: BTGrpcClient | null = null; let mockServer: MockBTService | null = null; let healthCheckInterval: NodeJS.Timeout | null = null; // 声明一个变量来存储定时器 const window = getBrowserWindowRuntime(); // 初始化 gRPC 客户端 async function initializeGrpc() { try { if (IS_TEST_MODE) { console.log('启动模拟 gRPC 服务器...'); mockServer = new MockBTService(); await mockServer.start(GRPC_SERVER_PORT); // 给一点时间让服务器启动 await new Promise(resolve => setTimeout(resolve, 1000)); } // 创建 BTGrpcClient 实例连接到gRPC服务 btGrpcClient = new BTGrpcClient(); // 注册进度回调函数,用于接收下载进度更新 btGrpcClient.registerProgressCallback('all', (progress) => { const mainWindow = BrowserWindow.getFocusedWindow(); if (mainWindow) { mainWindow.webContents.send('grpc-progress-update', progress); } }); // 测试连接 setTimeout(async () => { try { const connected = await btGrpcClient!.testConnection(); console.log('gRPC 连接状态:', connected ? '已连接' : '未连接'); const mainWindow = BrowserWindow.getFocusedWindow(); if (mainWindow) { mainWindow.webContents.send('grpc-connection-status', { connected, isMock: IS_TEST_MODE }); } } catch (error) { console.error('连接测试失败:', error); } }, 2000); // 启动健康检查 startHealthCheck(); } catch (error) { console.error('gRPC 初始化失败:', error); } } // 启动健康检查 function startHealthCheck() { if (healthCheckInterval) { clearInterval(healthCheckInterval); } healthCheckInterval = setInterval(async () => { try { if (!btGrpcClient) return; const isConnected = await btGrpcClient.testConnection(); const mainWindow = BrowserWindow.getFocusedWindow(); if (mainWindow) { mainWindow.webContents.send('grpc-connection-status', { connected: isConnected, state: btGrpcClient.getConnectionState(), isMock: IS_TEST_MODE }); } } catch (error) { console.error('健康检查失败:', error); } }, 5000); // 每5秒检查一次 } // 应用启动时初始化 app.whenReady().then(() => { initializeGrpc(); }); // 应用退出时清理 app.on('before-quit', async () => { if (healthCheckInterval) { clearInterval(healthCheckInterval); } if (mockServer) { await mockServer.stop(); } }); // 添加 gRPC 相关的 IPC 处理程序 ipcMain.handle('grpc-start-download', async (event, config) => { try { if (!btGrpcClient) { return { success: false, error: 'gRPC客户端未初始化' }; } console.log('开始gRPC下载:', config); // gRPC客户端向服务端发起 StartDownload 调用 const result = await btGrpcClient.startDownload({ torrent_url: config.torrentUrl, item_name: config.itemName, item_id: config.itemId }); return { success: true, data: result }; } catch (error: any) { console.error('gRPC下载失败:', error); return { success: false, error: error.message || '未知错误', details: error.details }; } }); ipcMain.handle('grpc-stop-download', async (event, downloadId) => { try { if (!btGrpcClient) { return { success: false, error: 'gRPC客户端未初始化' }; } const result = await btGrpcClient.stopDownload(downloadId); return { success: true, data: result }; } catch (error: any) { return { success: false, error: error.message || '未知错误' }; } }); ipcMain.handle('grpc-check-connection', async () => { if (!btGrpcClient) { return { connected: false, error: 'gRPC客户端未初始化' }; } return { connected: btGrpcClient.isConnected(), state: btGrpcClient.getConnectionState() }; }); // 重新连接 gRPC ipcMain.handle('grpc-reconnect', async () => { try { if (btGrpcClient) { btGrpcClient.reconnect(); return { success: true, message: '正在重新连接' }; } else { await initializeGrpc(); return { success: true, message: '正在初始化连接' }; } } catch (error: any) { return { success: false, error: error.message || '重新连接失败' }; } }); // 监听渲染进程发送的消息 ipcMain.handle('getPlatform', () => { return `hi, i'm from ${process.platform}`; }); // 窗口控制:最小化,退出全屏 ipcMain.on('close-app', () => { app.quit(); }); ipcMain.on('minimize-app', () => { window?.minimize(); }); ipcMain.on('exit-kiosk', () => { if (window) { window.setFullScreen(false); } }); ipcMain.handle('get-deviceid',async()=>{ const deviceId = await getDeviceId(); console.log(`Using device ID: ${deviceId}`); // TODO:传给后端 }) /* IPC 处理应用有线网络配置 */ ipcMain.handle('apply-wired-config',async(event,config)=>{ // return { // success: true, // message: '网络配置已成功应用' // }; try{ console.log('应用网络配置:', config); // 获取有线连接名称 const connectionName = await getWiredConnectionName(); console.log('有线连接名称:', connectionName); if(config.method==='static'){ // 使用nmcli配置静态IP,需要使用sudo权限,一次性设置所有参数 let modifyCmd = `echo "unis@123" | sudo -S nmcli connection modify "${connectionName}" ipv4.method manual ipv4.addresses "${config.ipv4}/${netmaskToCidr(config.subnetMask)}" ipv4.gateway "${config.ipv4Gateway}"`; const dnsServers = [config.primaryDns, config.secondaryDns].filter(Boolean).join(','); modifyCmd += ` ipv4.dns "${dnsServers}"`; // 添加 IPv6 配置(如果存在 ipv6Gateway)????ipv6和长度需要吗?ui只写了ipv6网关 // ipv6PrefixLength 是 IPv6 地址的前缀长度,类似于 IPv4 中的子网掩码。???? if (config.ipv6 && config.ipv6Gateway) { modifyCmd += ` ipv6.method manual ipv6.addresses "${config.ipv6}/${config.ipv6PrefixLength || 64}" ipv6.gateway "${config.ipv6Gateway}"`; } // 执行配置命令 console.log('执行命令:', modifyCmd.replace('unis@123', '***')); await execAsync(modifyCmd); // 重新激活连接 await execAsync(`echo "unis@123" | sudo -S nmcli connection up "${connectionName}"`); }else{ // DHCP配置,一次性设置所有参数 const modifyCmd = `echo "unis@123" | sudo -S nmcli connection modify "${connectionName}" ipv4.method auto ipv4.addresses "" ipv4.gateway "" ipv4.dns ""`; // 执行配置命令 console.log('执行命令:', modifyCmd.replace('unis@123', '***')); await execAsync(modifyCmd); // 重新激活连接 await execAsync(`echo "unis@123" | sudo -S nmcli connection up "${connectionName}"`); } return { success: true, message: '网络配置已成功应用' }; }catch(error:unknown){ console.error('应用网络配置失败:', error); return { success: false, message: `配置失败: ${error instanceof Error ? error.message : String(error || '未知错误')}` }; } })