Henry_Du 9c5d6e9659 fix(audio): 修复线缆 token 死锁(holder=CE-01) + 同组 approaching 等优先级饿死 + 线缆太长前端主机听不到
1. releaseCableToken(L688): 去掉 audioId 严格匹配, 只要 stationName 对就释放
   修复: CE-01 因 audioId 在 setTimeout/release 分支里 miss-match, token 永远不释放,
   导致同组其它站 approaching 100% 被 deny reason=lower_priority holder=CE-01

2. acquireCableToken(L549): 新增 equal-prio-timeout 抢占, 同一线缆分组多站连续
   approaching(p=2) 时不会再出现 holder 永远持住的死锁: 旧 token 持有超过
   max(30s, durHint+30s) 后, 等优先级新请求可强制切换 (日志 WARN: equal-prio switch)

3. Cable token watchdog(每20s扫描): holder 站点所有连接断开立刻强制释放
   (holder_offline); 最长持有 10min 兜底强制释放 (max_hold_timeout). 彻底避免
   音乐循环/循环临时广播 崩溃后 token 泄漏永远释放不了的情况

4. 线缆太长前端主机听不到 (架构修复):
   旧方案: sendAudioBufferToStation / sendLiveWavChunksToStation 里全部 WS 消息
   (audio_start + audio_chunk + audio_end) 只发给站点唯一 masterWs 连接, 若
   master 物理位置在线缆尾部, 中间节点断链, 线缆最前面主机就完全收不到音频
   新方案: 新增 sendWsToAllConnectionsOfStation + sendBinaryToAllConnectionsOfStation
   (L503-L520), 所有 (audio_start/end, cable_token_granted, audio_preempt) JSON 消息
   及所有 binary WAV 分块, 广播到该站点 getAllStationConnections 返回的 *所有*
   已连接 WS node, 每台主机独立从云端服务器拿一份流, 不再依赖线缆上 master 转发
   对 10 站长线缆场景, 只要 node 还连着云端, 就肯定能收到音频, 彻底避免前端
   主机因线缆中段节点断网/掉电听不到音频的故障

端到端单元测试 5/5 PASS:
  A releaseCableToken audioId 不严格匹配 PASS
  B p=2 approaching dur=8s age=70s 时 equal-prio 切换 PASS
  B2 p=2 age=5s 时不抢占 PASS (防抖动)
  C watchdog holder_offline 检测后立刻释放 PASS
  D 同站 4 个 node 同时都收到 audio_start 消息 PASS (前端主机不漏消息)

v1.0.114
2026-08-17 19:48:36 +08:00
2026-08-15 23:13:10 +08:00
S
Description
No description provided
123 MiB
Languages
HTML 49.3%
JavaScript 25.5%
Lua 25.2%