1.重构实时消息WebSocket连接

2.MySQL备份
This commit is contained in:
2026-04-24 13:49:38 +08:00
parent d69412a0f7
commit fd324f2882
54 changed files with 2396 additions and 2638 deletions

View File

@@ -1,7 +1,7 @@
<template>
<div class="default-main">
<el-alert type="info" :title="t('game.live.tip')" show-icon class="mb-12" />
<el-alert :type="pushConnected ? 'success' : 'error'" :title="pushConnected ? t('game.live.push_connected') : t('game.live.push_disconnected')" show-icon class="mb-12" />
<el-alert type="info" :title="t('game.live.push_disconnected')" show-icon class="mb-12" />
<el-alert
v-if="snapshot.runtime_enabled === false && !snapshot.maintenance_ui"
type="warning"
@@ -190,7 +190,7 @@
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage } from 'element-plus'
import createAxios, { getPushScriptUrl } from '/@/utils/axios'
import createAxios from '/@/utils/axios'
interface Snapshot {
record: anyObj | null
@@ -219,7 +219,6 @@ interface Snapshot {
const { t } = useI18n()
const loading = ref(false)
const pushConnected = ref(false)
const snapshot = reactive<Snapshot>({
record: null,
bets: [],
@@ -256,10 +255,7 @@ const serverSkewSeconds = ref(0)
const clockTick = ref(0)
let clockTimer: number | null = null
let pushClient: any = null
let pushChannel: any = null
let pollTimer: number | null = null
let pushWatchdogTimer: number | null = null
function formatPicks(v: unknown): string {
if (Array.isArray(v)) return JSON.stringify(v)
@@ -417,59 +413,6 @@ async function submitVoidPeriod(): Promise<void> {
}
}
async function initPush() {
const cfgRes = await createAxios({ url: '/admin/game.Live/pushConfig', method: 'get', showCodeMessage: false })
if (cfgRes.code !== 1 || !cfgRes.data) {
pushConnected.value = false
return
}
const { url, app_key, channel, event } = cfgRes.data
try {
await loadPushJs()
} catch {
pushConnected.value = false
startPolling()
return
}
const PushCtor = (window as any).Push
if (!PushCtor) {
pushConnected.value = false
startPolling()
return
}
try {
pushClient = new PushCtor({ url, app_key })
pushChannel = pushClient.subscribe(channel)
pushConnected.value = false
pushChannel.on('pusher:subscription_succeeded', () => {
pushConnected.value = true
})
startPushWatchdog()
stopPolling()
pushChannel.on(event, (payload: anyObj) => {
pushConnected.value = true
mergeLiveSnapshot(payload)
})
} catch {
pushConnected.value = false
startPolling()
}
}
async function loadPushJs() {
if ((window as any).Push) {
return
}
await new Promise<void>((resolve, reject) => {
const script = document.createElement('script')
script.src = getPushScriptUrl()
script.onload = () => resolve()
script.onerror = () => reject(new Error('load push.js failed'))
document.head.appendChild(script)
})
}
async function onCalculate() {
if (!snapshot.record) return
calcLoading.value = true
@@ -528,24 +471,11 @@ onMounted(async () => {
clockTick.value++
}, 1000)
await loadSnapshot()
try {
await initPush()
} catch {
pushConnected.value = false
startPolling()
}
startPolling()
})
onUnmounted(() => {
try {
if (pushClient && typeof pushClient.disconnect === 'function') {
pushClient.disconnect()
}
} catch {
// ignore
}
stopPolling()
stopPushWatchdog()
if (clockTimer !== null) {
window.clearInterval(clockTimer)
clockTimer = null
@@ -568,30 +498,6 @@ function stopPolling() {
}
}
function startPushWatchdog() {
if (pushWatchdogTimer !== null) {
return
}
pushWatchdogTimer = window.setInterval(() => {
if (!pushClient || !pushClient.connection) {
pushConnected.value = false
return
}
const state = String(pushClient.connection.state || '')
// push.jsonOpen 后长期为 connecting必须收到 pusher:connection_established 才变 connected。
// 把 connecting 当「已连接」会误报绿条Nginx 只完成握手、帧未透传时 DevTools 消息列表为空)。
if (state === 'disconnected') {
pushConnected.value = false
}
}, 1000)
}
function stopPushWatchdog() {
if (pushWatchdogTimer !== null) {
window.clearInterval(pushWatchdogTimer)
pushWatchdogTimer = null
}
}
</script>
<style scoped lang="scss">