Fix: relay WebSocket messages as text frames (browsers got Blobs they could not parse)
Root cause of 'track does not start': the server re-broadcast incoming frames as binary (Buffer), so the browser output page received Blobs, JSON.parse failed, and every command (playTrack, etc.) was silently dropped — only the text-encoded lastEffect sync got through. Broadcast as text now; net.js also handles Blob defensively. Also: no-store for app assets + kiosk --disk-cache-size=1 so redeploys always take effect; /api/clients debug endpoint; /api/peaks duration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0230ee1d6
commit
1a66a46b1f
4 files changed
+22
-4
No files matched your search
+7
-2
@@ -14,11 +14,16 @@
|
||||
ws.onopen = () => { ready = true; setStatus(true); while (queue.length) ws.send(queue.shift()); };
|
||||
ws.onclose = () => { ready = false; setStatus(false); setTimeout(connect, 1000); }; // survive server restarts
|
||||
ws.onerror = () => { try { ws.close(); } catch (e) {} };
|
||||
ws.onmessage = (ev) => {
|
||||
let m; try { m = JSON.parse(ev.data); } catch (e) { return; }
|
||||
const handle = (txt) => {
|
||||
let m; try { m = JSON.parse(txt); } catch (e) { return; }
|
||||
if (m.ch === 'ctl') ctlCbs.forEach(cb => cb(m.msg));
|
||||
else if (m.ch === 'rpt') rptCbs.forEach(cb => cb(m.msg));
|
||||
};
|
||||
ws.onmessage = (ev) => {
|
||||
if (typeof ev.data === 'string') handle(ev.data);
|
||||
else if (ev.data && typeof ev.data.text === 'function') ev.data.text().then(handle); // Blob
|
||||
else handle(String(ev.data));
|
||||
};
|
||||
}
|
||||
connect();
|
||||
|
||||
|
||||
@@ -341,6 +341,9 @@ djv.onControl(async (m) => {
|
||||
djv.report({ type: 'playState', playing: true });
|
||||
} catch (e) { djv.report({ type: 'error', message: e.message }); }
|
||||
break;
|
||||
case 'diag':
|
||||
djv.report({ type: 'diag', stage: 'poll', ctx: audio.ctx.state, mode: audio.mode });
|
||||
break;
|
||||
case 'playVideoTrack':
|
||||
try {
|
||||
audio.setTrim(m.start || 0, m.end || 0);
|
||||
|
||||
@@ -11,4 +11,5 @@ exec "$BIN" \
|
||||
--ozone-platform=wayland \
|
||||
--ignore-gpu-blocklist \
|
||||
--test-type \
|
||||
--disk-cache-size=1 --disable-back-forward-cache \
|
||||
"$URL" >/tmp/chromium-kiosk.log 2>&1
|
||||
@@ -30,7 +30,11 @@ function ffmpegPath() {
|
||||
|
||||
const app = express();
|
||||
app.use(express.json({ limit: '4mb' }));
|
||||
app.use(express.static(path.join(ROOT, 'public')));
|
||||
// Never cache the app shell (HTML/JS/CSS): on a local appliance the network is
|
||||
// fast and this guarantees the kiosk/phone always run the latest deployed code.
|
||||
// Media files (large) stay cacheable.
|
||||
app.use((req, res, next) => { if (!req.path.startsWith('/media')) res.set('Cache-Control', 'no-store'); next(); });
|
||||
app.use(express.static(path.join(ROOT, 'public'), { etag: false, lastModified: false }));
|
||||
app.use('/media', express.static(MEDIA_DIR));
|
||||
app.use('/svg', express.static(SVG_DIR));
|
||||
|
||||
@@ -63,6 +67,8 @@ app.post('/api/upload', upload.array('files'), (req, res) => {
|
||||
res.json({ ok: true, count: (req.files || []).length });
|
||||
});
|
||||
|
||||
app.get('/api/clients', (_req, res) => { res.json([...wss.clients].map((c) => ({ role: c.role, open: c.readyState === 1 }))); });
|
||||
|
||||
app.get('/api/svgs', (_req, res) => {
|
||||
let files = [];
|
||||
try { files = fs.readdirSync(SVG_DIR).filter(f => /\.svg$/i.test(f)); } catch (e) {}
|
||||
@@ -163,7 +169,10 @@ wss.on('connection', (ws, req) => {
|
||||
}
|
||||
});
|
||||
function broadcast(role, data) {
|
||||
wss.clients.forEach(c => { if (c.readyState === 1 && c.role === role) c.send(data); });
|
||||
// Always send a TEXT frame: browsers receive binary frames as Blob and would
|
||||
// fail JSON.parse, so commands would silently never reach the output page.
|
||||
const txt = typeof data === 'string' ? data : data.toString();
|
||||
wss.clients.forEach(c => { if (c.readyState === 1 && c.role === role) c.send(txt); });
|
||||
}
|
||||
|
||||
server.listen(PORT, () => {
|
||||
|
||||
Reference in new issue
Block a user