fix: stabilize datasource progress and websocket flow

This commit is contained in:
linkong
2026-04-01 12:04:28 +08:00
parent 126d4dadb7
commit b8f70f8b71
11 changed files with 408 additions and 134 deletions

View File

@@ -14,6 +14,7 @@ import { Link } from 'react-router-dom'
import axios from 'axios'
import { useAuthStore } from '../../stores/auth'
import AppLayout from '../../components/AppLayout/AppLayout'
import { useWebSocket } from '../../hooks/useWebSocket'
import { formatDateTimeZhCN } from '../../utils/datetime'
const { Title, Text } = Typography
@@ -150,54 +151,21 @@ function Dashboard() {
fetchStats()
}, [token, clearAuth])
useEffect(() => {
if (!token) return
let ws: WebSocket | null = null
let reconnectTimer: ReturnType<typeof setTimeout> | null = null
const connectWs = () => {
try {
ws = new WebSocket(`ws://localhost:8000/ws?token=${token}`)
ws.onopen = () => {
setWsConnected(true)
ws?.send(JSON.stringify({ type: 'subscribe', data: { channels: ['dashboard'] } }))
}
ws.onmessage = (event) => {
try {
const msg = JSON.parse(event.data)
if (msg.type === 'data_frame' && msg.channel === 'dashboard') {
const nextStats = msg.payload?.stats as Stats
cachedDashboardStats = nextStats
setStats(nextStats)
}
} catch (e) {
console.error('Parse WS message error:', e)
}
}
ws.onclose = () => {
setWsConnected(false)
reconnectTimer = setTimeout(connectWs, 3000)
}
ws.onerror = () => {
setWsConnected(false)
}
} catch (e) {
console.error('WS connect error:', e)
const { connected: dashboardSocketConnected } = useWebSocket({
autoConnect: true,
autoSubscribe: ['dashboard'],
onMessage: (message) => {
if (message.type === 'data_frame' && message.channel === 'dashboard' && message.payload?.stats) {
const nextStats = message.payload.stats as Stats
cachedDashboardStats = nextStats
setStats(nextStats)
}
}
},
})
connectWs()
return () => {
ws?.close()
if (reconnectTimer) clearTimeout(reconnectTimer)
}
}, [token])
useEffect(() => {
setWsConnected(dashboardSocketConnected)
}, [dashboardSocketConnected])
const handleRetry = () => {
window.location.reload()
@@ -376,8 +344,8 @@ function Dashboard() {
if (loading && !stats) {
return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
<Spin size="large" tip="加载中..." />
<div style={{ height: '100vh' }}>
<Spin size="large" tip="加载中..." fullscreen />
</div>
)
}