import { useEffect, useRef } from "react"; import dayjs from "dayjs"; import { useStartupCheck } from "@/hooks/useStartupCheck"; import { usePreventDefault } from "@/hooks/usePreventDefaultEventListener"; import { useGlobalShortcut } from "@/hooks/useGlobalShortcut"; import { useRecreateTheCircuit } from "@/hooks/useRecreateTheCircuit"; import { useCoreConfig } from "@/hooks/useCoreConfig"; import { useDispatch } from "react-redux"; import { setMaliciousNodeList, setNodeDownList, setWeb3List, setWeb3List2, } from "@/store/web3Slice"; import type { AppDispatch } from "@/store"; import eventBus, { eventTypes } from "@/utils/eventBus"; import { WebSocketClient } from "@/utils/webSocketClientV2"; import { blockChainApi } from "@/api/block"; import { getRandomCountryKey } from "@/data"; import Titlebar from "@/components/Titlebar"; import Layout from "@/layout"; import Tray from "@/components/Tray"; function App() { // 执行启动自检 useStartupCheck(); // 阻止默认事件 usePreventDefault(); // 注册全局快捷方式 useGlobalShortcut(); // 当核心启动时重新创建电路 useRecreateTheCircuit(); // 读取配置,若文件不存在则持久化到本地 `%APPDATA%/com.paw.paw-gui` const { loadCoreConfig } = useCoreConfig(); loadCoreConfig(); const dispatch = useDispatch(); const eventsWsRef = useRef(null); const blockchainTimerRef = useRef(null); const wsInitializedRef = useRef(false); // 处理 WebSocket 消息 const handleWebSocketMessage = (msg: any) => { try { const msgData = msg ? JSON.parse(msg.data) : {}; console.log("Received WebSocket message:", msgData); if (msgData?.code === 0) { switch (msgData.event) { case eventTypes.NODE_UP: console.log("节点上线"); break; case eventTypes.NODE_DOWN: // 添加下线节点到store 里面 if (msgData.data.name) { // 获取一个随机的国家code const countryCode = getRandomCountryKey(); dispatch( setNodeDownList({ name: msgData.data.name, code: countryCode, }) ); } console.log("节点下线"); break; case eventTypes.MALICIOUS_NODE: // 添加恶意节点到store 里面 if (msgData.data.name) { // 获取一个随机的国家code const countryCode = getRandomCountryKey(); dispatch( setMaliciousNodeList({ name: msgData.data.name, code: countryCode, }) ); } console.log("检测到恶意节点"); break; case eventTypes.NODE_INIT_COMPLATE: if (eventsWsRef.current?.isWebSocketConnected()) { eventsWsRef.current.sendMessage( JSON.stringify({ ...msgData, event: eventTypes.NODE_ADD, }) ); console.log("节点预配置完成:", { ...msgData, event: eventTypes.NODE_ADD, }); } break; case eventTypes.NODE_REMOVE: console.log("节点清除"); break; case eventTypes.NODE_ADD: console.log("添加节点"); break; default: break; } } } catch (error) { console.error("Error processing WebSocket message:", error); } }; // 初始化 WebSocket 连接 const initWebSocket = async () => { if (eventsWsRef.current) return; console.log("Initializing WebSocket connection..."); eventsWsRef.current = new WebSocketClient( "ws://47.82.97.10:8080/events", {}, { autoReconnect: true, maxReconnectAttempts: 10, reconnectDelay: 2000, } ); const connected = await eventsWsRef.current.connect(); if (connected) { console.log("WebSocket connected successfully"); eventsWsRef.current.addListener(handleWebSocketMessage); wsInitializedRef.current = true; } else { console.error("Failed to establish WebSocket connection"); } }; // 设置事件总线监听器 const setupEventBusListeners = () => { console.log("执行了没") // 添加节点 eventBus.on(eventTypes.NODE_ADD, (data: any) => { console.log("添加节点", data); if (eventsWsRef.current?.isWebSocketConnected()) { const timestamp = dayjs().unix(); const params = { code: 0, event: eventTypes.NODE_ADD, data: data, timestamp, }; eventsWsRef.current.sendMessage(JSON.stringify(params)); } else { console.warn("WebSocket not connected, can't send NODE_ADD message"); } }); // 节点预配置事件 eventBus.on(eventTypes.NODE_INIT, (data: any) => { console.log("节点预配置", data); if (eventsWsRef.current?.isWebSocketConnected()) { const timestamp = dayjs().unix(); const params = { code: 0, event: "node_init", data: {}, timestamp: timestamp, }; eventsWsRef.current.sendMessage(JSON.stringify(params)); } else { console.warn("WebSocket not connected, can't send NODE_INIT message"); } }); // 节点清除事件 eventBus.on(eventTypes.NODE_REMOVE, (data: any) => { console.log("节点清除", data); if (eventsWsRef.current?.isWebSocketConnected()) { const timestamp = dayjs().unix(); const params = { code: 0, event: eventTypes.NODE_REMOVE, data: { name: data, }, timestamp, }; eventsWsRef.current.sendMessage(JSON.stringify(params)); } else { console.warn("WebSocket not connected, can't send NODE_REMOVE message"); } }); }; // 清理事件总线监听器 const cleanupEventBusListeners = () => { eventBus.off(eventTypes.NODE_INIT); eventBus.off(eventTypes.NODE_REMOVE); }; // 启动区块链数据轮询 const startBlockchainPolling = () => { // 立即执行一次 fetchBlockchainData(); // 设置定时器定期获取数据 blockchainTimerRef.current = setInterval(fetchBlockchainData, 5000); }; // 获取区块链数据 const fetchBlockchainData = async () => { try { const blockRes = await blockChainApi.getLatestBlock(); const height = blockRes.data.block.last_commit.height; const txsRes = await blockChainApi.getTxsByBlock(height); const timer = txsRes.data.block.header.time; const txs = txsRes.data.txs; const balance = txs.reduce((acc: number, item: any) => { const blance = item.auth_info.fee.gas_limit * Number(blockChainApi.blockConfig.minimum_gas_price); return acc + blance; }, 0); const item = { height: height, txs: txs, timerstamp: dayjs(timer).format("HH:mm:ss"), balance, balanceToFixed: Number(balance).toFixed(3), }; dispatch(setWeb3List(item)); } catch (error) { console.error("Error fetching blockchain data:", error); } }; // 初始化所有服务 const initializeServices = async () => { // 初始化示例数据 dispatch( setWeb3List2([ { id: "6", name: "Cardano Wallet", payType: "ADA", status: "active", createdAt: 1737436420, upDatedAt: 5, balance: "65", address: "addr1qxck6ztj8lrxd0j2jz8f7tznzfu9wqv9qrplrh3r9eq8g9n0n3anjy2a4x54kd2sort3qvnc7mct82krlnpnxvl7v3sxmrv3f", privateKey: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi", publicKey: "addr1qxck6ztj8lrxd0j2jz8f7tznzfu9wqv9qrplrh3r9eq8g9n0n3anjy2a4x54kd2sort3qvnc7mct82krlnpnxvl7v3sxmrv3f", numberTransactions: "35", transactions: 1, txs: [], height: 1204, timerstamp: dayjs().format("HH:mm:ss"), balanceToFixed: 0, }, ]) ); // 初始化 WebSocket await initWebSocket(); // 设置事件总线 setupEventBusListeners(); // 启动区块链数据轮询 startBlockchainPolling(); }; // 清理所有资源 const cleanupServices = () => { // 清理区块链数据轮询 if (blockchainTimerRef.current) { clearInterval(blockchainTimerRef.current); blockchainTimerRef.current = null; } // 清理事件总线 cleanupEventBusListeners(); // 关闭 WebSocket 连接 if (eventsWsRef.current) { eventsWsRef.current.disconnect(); eventsWsRef.current = null; } wsInitializedRef.current = false; }; useEffect(() => { // 延迟初始化以确保组件完全挂载 const initTimer = setTimeout(() => { initializeServices(); }, 1000); // 组件卸载时清理资源 return () => { clearTimeout(initTimer); cleanupServices(); console.log("App component unmounted, all services cleaned up"); }; }, []); return (
); } export default App;