直播观众:negotiate 失败后恢复轮询;防并发 poll;长时 502 提示

Made-with: Cursor
This commit is contained in:
whm
2026-03-25 16:55:05 +08:00
parent 7e24a965bc
commit da0bcae823

View File

@@ -47,6 +47,8 @@ export function startViewing(videoEl, opts = {}) {
let ws = null
let pollTimer = null
let currentPollMs = pollMs
let pollInFlight = false
let upstreamErrorStreak = 0
let stopped = false
let blackFrameTimer = null
@@ -109,8 +111,12 @@ export function startViewing(videoEl, opts = {}) {
if (pollTimer) return
rebuildPeer()
currentPollMs = pollMs
upstreamErrorStreak = 0
schedulePollLoop()
poll()
// 下一轮再 poll避免从 poll() 内同步调用时 pollInFlight 仍为 true 导致被跳过
setTimeout(() => {
if (!stopped) poll()
}, 0)
}
async function negotiate() {
@@ -173,10 +179,17 @@ export function startViewing(videoEl, opts = {}) {
async function poll() {
if (stopped) return
if (pollInFlight) return
pollInFlight = true
try {
const { live, upstreamError } = await fetchLiveStatus()
if (upstreamError) {
onStatus('无法连接服务器(网关 502/离线),将放慢重试…')
upstreamErrorStreak += 1
const extra =
upstreamErrorStreak >= 6
? ' 若长时间如此,多为服务端未启动或网关异常,请刷新页面或联系管理员。'
: ''
onStatus(`无法连接服务器(网关 502/离线),将放慢重试…${extra}`)
const next = Math.min(Math.round(currentPollMs * 1.5), 30000)
if (next !== currentPollMs) {
currentPollMs = next
@@ -184,6 +197,7 @@ export function startViewing(videoEl, opts = {}) {
}
return
}
upstreamErrorStreak = 0
if (currentPollMs !== pollMs) {
currentPollMs = pollMs
schedulePollLoop()
@@ -195,12 +209,23 @@ export function startViewing(videoEl, opts = {}) {
}
onLive()
onStatus('检测到直播,正在连接…')
await negotiate()
try {
await negotiate()
} catch (err) {
onStatus(
err?.message
? `拉流连接失败:${err.message}`
: '拉流连接失败,将恢复轮询…'
)
resumePollingAfterDisconnect('')
}
return
}
onStatus('等待主播开播…')
} catch {
onStatus('无法获取直播状态')
} finally {
pollInFlight = false
}
}