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