Browse Source

feat: coalesce monitor play-url by session with TTL reuse

main
xiaosi 2 weeks ago
parent
commit
91e88fb2aa
  1. 41
      src/composables/useMonitorLive.js

41
src/composables/useMonitorLive.js

@ -16,6 +16,7 @@ const STOP_TIMEOUT_MS = 60_000
const PLAY_RETRY_MAX = 3
const PLAY_EXPIRE_FALLBACK_SEC = 270
const PLAY_REFRESH_LEAD_MS = 30_000
const PLAY_URL_FRESH_MS = PLAY_REFRESH_LEAD_MS
const LEASE_INVALID_CODE = 57006
function isFatalPlayMediaError(err) {
@ -73,6 +74,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
})
let playURLRequest = null
let playURLRequestSessionId = ''
let disposed = false
let openGen = 0
let rejoinBusy = false
@ -108,6 +110,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
live.heartbeatTimer = null
live.playRefreshTimer = null
playURLRequest = null
playURLRequestSessionId = ''
live.playUrl = ''
live.playUrlExpiresAt = 0
live.playRetryCount = 0
@ -116,6 +119,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
function resetLocal() {
clearTimers()
playURLRequest = null
playURLRequestSessionId = ''
live.session = null
live.dockId = ''
live.opening = false
@ -257,10 +261,20 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
// 成功返回 true;失败抛错,由调用方决定是否 onPlayError(避免互相递归)
// fromRetry: 播放错误触发的刷新不重置重试计数,避免无限重建
async function refreshPlayURLOnce({ fromRetry = false } = {}) {
async function refreshPlayURLOnce({ fromRetry = false, force = false } = {}) {
if (disposed || live.stopping || !live.dockId || !live.session?.id) return false
const dockId = live.dockId
const sessionId = live.session.id
const forceFetch = force || fromRetry
if (
!forceFetch &&
live.playUrl &&
live.playUrlExpiresAt * 1000 - Date.now() > PLAY_URL_FRESH_MS
) {
return true
}
const play = await getLivePlayURL(dockId, sessionId)
if (disposed || live.stopping || !live.session || live.session.id !== sessionId) return false
live.playUrl = play.playUrl || ''
@ -272,9 +286,28 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
}
function refreshPlayURL(options = {}) {
if (playURLRequest) return playURLRequest
const sessionId = live.session?.id
if (!sessionId) return Promise.resolve(false)
const forceFetch = Boolean(options.force || options.fromRetry)
if (
!forceFetch &&
live.playUrl &&
live.playUrlExpiresAt * 1000 - Date.now() > PLAY_URL_FRESH_MS
) {
return Promise.resolve(true)
}
if (playURLRequest && playURLRequestSessionId === sessionId) {
return playURLRequest
}
playURLRequestSessionId = sessionId
playURLRequest = refreshPlayURLOnce(options).finally(() => {
playURLRequest = null
if (playURLRequestSessionId === sessionId) {
playURLRequest = null
playURLRequestSessionId = ''
}
})
return playURLRequest
}
@ -286,7 +319,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) {
const delay = Math.max(5000, live.playUrlExpiresAt * 1000 - Date.now() - PLAY_REFRESH_LEAD_MS)
live.playRefreshTimer = window.setTimeout(async () => {
try {
await refreshPlayURL()
await refreshPlayURL({ force: true })
} catch (e) {
if (disposed || live.stopping) return
if (isLeaseInvalidError(e)) {

Loading…
Cancel
Save