修复websocket

This commit is contained in:
CN-JS-HuiBai
2026-04-07 12:20:09 +08:00
parent 73401309f2
commit 307a26c0db
3 changed files with 80 additions and 4 deletions

View File

@@ -296,7 +296,7 @@
<path
d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
</svg>
全球服务器分布
全球骨干分布
</h2>
<div class="chart-header-actions">
<button class="btn-icon" id="btnExpandGlobe" title="放大显示">

View File

@@ -551,8 +551,10 @@
const msg = JSON.parse(event.data);
if (msg.type === 'overview') {
allServersData = msg.data.servers || [];
if (msg.data.latencies) {
currentLatencies = msg.data.latencies;
}
updateDashboard(msg.data);
updateMap2D(allServersData);
}
} catch (err) {
console.error('WS Message Error:', err);
@@ -1127,8 +1129,20 @@
// Update server table
renderFilteredServers();
// Update globe
// Update globe (latencies already updated in ws message handler)
updateMap2D(data.servers || []);
// Real-time update for server detail modal if open
if (dom.serverDetailModal.classList.contains('active') && currentServerDetail.instance) {
const currentS = (data.servers || []).find(s =>
s.instance === currentServerDetail.instance &&
s.job === currentServerDetail.job &&
s.source === currentServerDetail.source
);
if (currentS) {
updateServerDetailMetrics(currentS);
}
}
// Flash animation
if (previousMetrics) {
@@ -1138,6 +1152,41 @@
previousMetrics = data;
}
// Real-time update for core server detail metrics (called from WebSocket broadcast)
function updateServerDetailMetrics(server) {
if (!server) return;
// Update the values displayed in the metric header cards within the detail modal
const metrics = [
{ key: 'cpuBusy', label: 'CPU 使用率', value: `
<div style="display: flex; align-items: baseline; gap: 8px;">
<span style="font-weight: 700; font-size: 1.1rem;">${formatPercent(server.cpuPercent)}</span>
</div>` },
{ key: 'memUsedPct', label: '内存使用率 (RAM)', value: formatPercent(server.memPercent) },
{ key: 'rootFsUsedPct', label: '根分区使用率 (/)', value: formatPercent(server.diskPercent) },
{ key: 'netRx', label: '网络接收速率 (RX)', value: formatBandwidth(server.netRx) },
{ key: 'netTx', label: '网络发送速率 (TX)', value: formatBandwidth(server.netTx) }
];
metrics.forEach(m => {
const el = document.getElementById(`metric-${m.key}`);
if (el) {
const valEl = el.querySelector('.metric-value');
if (valEl) valEl.innerHTML = m.value;
}
});
// Also update current active history charts if they are open
Object.keys(currentServerDetail.charts).forEach(key => {
const el = document.getElementById(`metric-${key}`);
if (el && el.classList.contains('active')) {
// If the chart is open, we don't automatically refresh the history (too heavy)
// But we could append the latest point if we wanted to.
// For now, updating the summary numbers is enough for "real-time".
}
});
}
function renderFilteredServers() {
let filtered = allServersData;
if (currentSourceFilter !== 'all') {

View File

@@ -1026,7 +1026,34 @@ function broadcast(data) {
async function broadcastMetrics() {
try {
const overview = await getOverview();
broadcast({ type: 'overview', data: overview });
// Also include latencies in the broadcast to make map lines real-time
const [routes] = await db.query(`
SELECT r.*, s.url, s.type as source_type
FROM latency_routes r
JOIN prometheus_sources s ON r.source_id = s.id
`);
const latencyResults = await Promise.all(routes.map(async (route) => {
let latency = await cache.get(`latency:route:${route.id}`);
if (latency === null && route.source_type === 'prometheus') {
latency = await prometheusService.getLatency(route.url, route.latency_target);
}
return {
id: route.id,
source: route.latency_source,
dest: route.latency_dest,
latency: latency
};
}));
broadcast({
type: 'overview',
data: {
...overview,
latencies: latencyResults
}
});
} catch (err) {
// console.error('WS Broadcast error:', err.message);
}