🐞 fix: 修复网络监控无法使用的问题

This commit is contained in:
zhiyu1998 2024-11-22 20:41:43 +08:00
parent caf1d7e550
commit 5c382c8a24
3 changed files with 84 additions and 33 deletions

View File

@ -15,6 +15,7 @@
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"next": "^14.2.16", "next": "^14.2.16",
"node-id3": "^0.2.6", "node-id3": "^0.2.6",
"node-os-utils": "^1.3.7",
"os-utils": "^0.0.14", "os-utils": "^0.0.14",
"p-queue": "^8.0.1", "p-queue": "^8.0.1",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",

View File

@ -1,48 +1,92 @@
import { promises as fs } from 'fs';
import os from 'os'; import os from 'os';
import si from 'systeminformation';
let lastBytesReceived = 0; let lastBytesReceived = 0;
let lastBytesSent = 0; let lastBytesSent = 0;
let lastTimestamp = Date.now(); let lastTimestamp = Date.now();
function getNetworkStats() { async function getLinuxStats() {
const networkInterfaces = os.networkInterfaces(); const data = await fs.readFile('/proc/net/dev', 'utf8');
const lines = data.trim().split('\n');
let bytesReceived = 0; let bytesReceived = 0;
let bytesSent = 0; let bytesSent = 0;
// 累加所有网络接口的数据 for (let i = 2; i < lines.length; i++) {
Object.values(networkInterfaces).forEach(interfaces => { const line = lines[i].trim();
interfaces.forEach(netInterface => { const parts = line.split(/\s+/);
if (netInterface.internal === false) {
bytesReceived += netInterface.bytes_received || 0; if (parts[0].startsWith('lo:')) continue;
bytesSent += netInterface.bytes_sent || 0;
bytesReceived += parseInt(parts[1], 10);
bytesSent += parseInt(parts[9], 10);
}
return { bytesReceived, bytesSent };
}
async function getWindowsStats() {
const networkStats = await si.networkStats();
let bytesReceived = 0;
let bytesSent = 0;
for (const stat of networkStats) {
bytesReceived += stat.rx_bytes || 0;
bytesSent += stat.tx_bytes || 0;
}
return { bytesReceived, bytesSent };
}
async function getNetworkStats() {
try {
const platform = os.platform();
let bytesReceived = 0;
let bytesSent = 0;
if (platform === 'linux') {
const stats = await getLinuxStats();
bytesReceived = stats.bytesReceived;
bytesSent = stats.bytesSent;
} else {
const stats = await getWindowsStats();
bytesReceived = stats.bytesReceived;
bytesSent = stats.bytesSent;
} }
});
});
const now = Date.now(); const now = Date.now();
const timeDiff = (now - lastTimestamp) / 1000; // 转换为秒 const timeDiff = (now - lastTimestamp) / 1000;
// 计算速率(字节/秒) const downloadSpeed = Math.max(0, (bytesReceived - lastBytesReceived) / timeDiff);
const downloadSpeed = (bytesReceived - lastBytesReceived) / timeDiff; const uploadSpeed = Math.max(0, (bytesSent - lastBytesSent) / timeDiff);
const uploadSpeed = (bytesSent - lastBytesSent) / timeDiff;
// 更新上次的值
lastBytesReceived = bytesReceived; lastBytesReceived = bytesReceived;
lastBytesSent = bytesSent; lastBytesSent = bytesSent;
lastTimestamp = now; lastTimestamp = now;
return { return {
downloadSpeed: (downloadSpeed / 1024).toFixed(2), // KB/s downloadSpeed: (downloadSpeed / 1024).toFixed(2),
uploadSpeed: (uploadSpeed / 1024).toFixed(2), // KB/s uploadSpeed: (uploadSpeed / 1024).toFixed(2),
totalReceived: (bytesReceived / (1024 * 1024 * 1024)).toFixed(2), // GB totalReceived: (bytesReceived / (1024 * 1024 * 1024)).toFixed(2),
totalSent: (bytesSent / (1024 * 1024 * 1024)).toFixed(2), // GB totalSent: (bytesSent / (1024 * 1024 * 1024)).toFixed(2),
timestamp: now timestamp: now
}; };
} catch (error) {
console.error('获取网络统计信息失败:', error);
return {
downloadSpeed: "0",
uploadSpeed: "0",
totalReceived: "0",
totalSent: "0",
timestamp: Date.now()
};
}
} }
export async function GET() { export async function GET() {
try { try {
const stats = getNetworkStats(); const stats = await getNetworkStats();
return new Response(JSON.stringify(stats), { return new Response(JSON.stringify(stats), {
status: 200, status: 200,
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
@ -51,6 +95,6 @@ export async function GET() {
return new Response(JSON.stringify({ error: error.message }), { return new Response(JSON.stringify({ error: error.message }), {
status: 500, status: 500,
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
}) });
} }
} }

View File

@ -116,8 +116,8 @@ export default function Network() {
return ( return (
<div className="container mx-auto p-8"> <div className="container mx-auto p-8">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8"> <div className="grid grid-cols-1 gap-8">
<div className="card bg-base-100 shadow-xl col-span-1 lg:col-span-3"> <div className="card bg-base-100 shadow-xl">
<div className="card-body"> <div className="card-body">
<h2 className="card-title text-lg font-bold">网络监控</h2> <h2 className="card-title text-lg font-bold">网络监控</h2>
<div className="flex justify-between mb-4"> <div className="flex justify-between mb-4">
@ -130,8 +130,14 @@ export default function Network() {
<p>总接收: {networkData.totalReceived} GB</p> <p>总接收: {networkData.totalReceived} GB</p>
</div> </div>
</div> </div>
<div className="h-[300px]"> <div className="w-full h-[300px]">
<Line data={chartData} options={chartOptions} /> <Line
data={chartData}
options={{
...chartOptions,
maintainAspectRatio: false,
}}
/>
</div> </div>
</div> </div>
</div> </div>