refactor: migrate real-time log viewing from WebSocket to SSE with JSON wrapping
This commit is contained in:
@@ -80,7 +80,7 @@ const deleteLogId = ref<string | null>(null)
|
||||
|
||||
const wsContent = ref('')
|
||||
const isWsLoading = ref(false)
|
||||
let logSocket: WebSocket | null = null
|
||||
let logSource: EventSource | null = null
|
||||
|
||||
|
||||
import { decompressFromBase64 } from '@/utils/decompress'
|
||||
@@ -136,12 +136,9 @@ function handlePageChange(page: number) {
|
||||
}
|
||||
|
||||
async function selectLog(log: TaskLog) {
|
||||
if (logSocket) {
|
||||
logSocket.onopen = null
|
||||
logSocket.onmessage = null
|
||||
logSocket.onerror = null
|
||||
logSocket.onclose = null
|
||||
logSocket.close()
|
||||
if (logSource) {
|
||||
logSource.close()
|
||||
logSource = null
|
||||
}
|
||||
|
||||
// 清理旧定时器
|
||||
@@ -198,23 +195,28 @@ async function selectLog(log: TaskLog) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
|
||||
const protocol = window.location.protocol
|
||||
const host = window.location.host
|
||||
const baseUrl = (window as any).__BASE_URL__ || ''
|
||||
const apiVersion = (window as any).__API_VERSION__ || '/api/v1'
|
||||
const wsUrl = `${protocol}//${host}${baseUrl}${apiVersion}/logs/ws?log_id=${log.id}`
|
||||
const sseUrl = `${protocol}//${host}${baseUrl}${apiVersion}/logs/sse?log_id=${log.id}`
|
||||
|
||||
logSocket = new WebSocket(wsUrl)
|
||||
logSource = new EventSource(sseUrl)
|
||||
|
||||
logSocket.onopen = () => {
|
||||
logSource.onopen = () => {
|
||||
isWsLoading.value = false
|
||||
console.log('[LogWS] Connection opened')
|
||||
console.log('[LogSSE] Connection opened')
|
||||
}
|
||||
|
||||
logSocket.onmessage = (event) => {
|
||||
logSource.onmessage = (event) => {
|
||||
isWsLoading.value = false
|
||||
wsContent.value += event.data
|
||||
try {
|
||||
const data = JSON.parse(event.data)
|
||||
wsContent.value += data.text || ''
|
||||
} catch {
|
||||
wsContent.value += event.data
|
||||
}
|
||||
// 自动滚动到底部
|
||||
nextTick(() => {
|
||||
const pre = document.querySelector('.log-pre')
|
||||
@@ -222,15 +224,13 @@ async function selectLog(log: TaskLog) {
|
||||
})
|
||||
}
|
||||
|
||||
logSocket.onerror = (e) => {
|
||||
logSource.onerror = (e) => {
|
||||
isWsLoading.value = false
|
||||
console.error('[LogWS] Connection error', e)
|
||||
toast.error('日志连接异常')
|
||||
}
|
||||
|
||||
logSocket.onclose = (e) => {
|
||||
isWsLoading.value = false
|
||||
console.log('[LogWS] Connection closed', e.code, e.reason)
|
||||
console.error('[LogSSE] Connection error/closed', e)
|
||||
if (logSource) {
|
||||
logSource.close()
|
||||
logSource = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,13 +239,9 @@ function closeDetail() {
|
||||
clearInterval(durationTimer)
|
||||
durationTimer = null
|
||||
}
|
||||
if (logSocket) {
|
||||
logSocket.onopen = null
|
||||
logSocket.onmessage = null
|
||||
logSocket.onerror = null
|
||||
logSocket.onclose = null
|
||||
logSocket.close()
|
||||
logSocket = null
|
||||
if (logSource) {
|
||||
logSource.close()
|
||||
logSource = null
|
||||
}
|
||||
selectedLog.value = null
|
||||
wsContent.value = ''
|
||||
|
||||
@@ -295,19 +295,13 @@ const selectedLog = ref<TaskLog | null>(null)
|
||||
const logContent = ref('')
|
||||
const logEmptyTitle = ref<string | undefined>(undefined)
|
||||
const logEmptyDesc = ref<string | undefined>(undefined)
|
||||
let logSocket: WebSocket | null = null
|
||||
let logSource: EventSource | null = null
|
||||
let durationTimer: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
function cleanupLogSocket() {
|
||||
if (logSocket) {
|
||||
logSocket.onopen = null
|
||||
logSocket.onmessage = null
|
||||
logSocket.onerror = null
|
||||
logSocket.onclose = null
|
||||
if (logSocket.readyState === WebSocket.CONNECTING || logSocket.readyState === WebSocket.OPEN) {
|
||||
logSocket.close()
|
||||
}
|
||||
logSocket = null
|
||||
if (logSource) {
|
||||
logSource.close()
|
||||
logSource = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,17 +354,26 @@ async function viewLogs(taskId: string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Connect WebSocket to load log content for running tasks
|
||||
// Connect SSE to load log content for running tasks
|
||||
cleanupLogSocket()
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
const protocol = window.location.protocol
|
||||
const host = window.location.host
|
||||
const baseUrl = (window as any).__BASE_URL__ || ''
|
||||
const apiVersion = (window as any).__API_VERSION__ || '/api/v1'
|
||||
const wsUrl = `${protocol}//${host}${baseUrl}${apiVersion}/logs/ws?log_id=${latestLog.id}`
|
||||
const sseUrl = `${protocol}//${host}${baseUrl}${apiVersion}/logs/sse?log_id=${latestLog.id}`
|
||||
|
||||
logSocket = new WebSocket(wsUrl)
|
||||
logSocket.onmessage = (event) => {
|
||||
logContent.value += event.data
|
||||
logSource = new EventSource(sseUrl)
|
||||
logSource.onmessage = (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data)
|
||||
logContent.value += data.text || ''
|
||||
} catch {
|
||||
logContent.value += event.data
|
||||
}
|
||||
}
|
||||
logSource.onerror = (e) => {
|
||||
console.error('[LogSSE] Connection error/closed', e)
|
||||
cleanupLogSocket()
|
||||
}
|
||||
|
||||
// 启动状态轮询
|
||||
|
||||
Reference in New Issue
Block a user