Browse Source

fix: harden live retry, stop confirm, heartbeat races

main
xiaosi 2 weeks ago
parent
commit
3da0c94e2a
  1. 16
      src/composables/useMonitorLive.js

16
src/composables/useMonitorLive.js

@ -141,7 +141,8 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
}
// 成功返回 true;失败抛错,由调用方决定是否 onPlayError(避免互相递归)
async function refreshPlayURL() {
// fromRetry: 播放错误触发的刷新不重置重试计数,避免无限重建
async function refreshPlayURL({ fromRetry = false } = {}) {
if (!live.dockId || !live.session?.id) return false
const sessionId = live.session.id
const play = await getLivePlayURL(live.dockId, sessionId)
@ -149,7 +150,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
live.playUrl = play.playUrl || ''
const nowSec = Math.floor(Date.now() / 1000)
live.playUrlExpiresAt = Number(play.expiresAt) || nowSec + PLAY_EXPIRE_FALLBACK_SEC
live.playRetryCount = 0
if (!fromRetry) live.playRetryCount = 0
schedulePlayRefresh()
return true
}
@ -172,9 +173,11 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
const delay = Math.max(5000, (Number(expiresAt) * 1000 - Date.now()) / 2)
live.heartbeatTimer = window.setTimeout(async () => {
if (!live.dockId || !live.session?.id) return
const dockId = live.dockId
const sessionId = live.session.id
try {
const result = await heartbeatLive(live.dockId, live.session.id)
if (!live.session) return
const result = await heartbeatLive(dockId, sessionId)
if (!live.session || live.session.id !== sessionId || live.dockId !== dockId) return
live.session = result.session
scheduleLiveHeartbeat(result.leaseExpiresAt)
if (result.session.phase === 'streaming' && !live.playUrl) {
@ -185,6 +188,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
}
}
} catch (e) {
if (!live.session || live.session.id !== sessionId || live.dockId !== dockId) return
ui.toast(e.message || '直播观看已结束')
await closeLive(false)
}
@ -200,7 +204,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
}
live.playRetryCount += 1
try {
await refreshPlayURL()
await refreshPlayURL({ fromRetry: true })
} catch (e) {
if (live.playRetryCount >= PLAY_RETRY_MAX) {
ui.toast(e?.message || err?.message || '播放失败')
@ -232,6 +236,8 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
['确认停止推流', '影响当前所有观看者']
)
if (!ok) return
// confirm 期间可能已关闭/切换会话,避免 stop 错 dock 或 wipe 新会话
if (!live.session || live.dockId !== dockId || live.session.id !== session.id) return
try {
await stopLive(dockId)
resetLocal()

Loading…
Cancel
Save