- Source (index.html): physics sim → pixel capture → delta XOR + RLE encode → WebSocket - Receiver (receiver.html): WebSocket → decode delta/keyframe → render + click interaction + RTT - Relay (relay.js): bidirectional WebSocket relay (pixels ↓ signals ↑) - 97% compression (18KB/frame vs 675KB raw RGBA) - Interactive: click on receiver → impulse force on source → round-trip latency measured - Frame types: 0x11 keyframe (every 60 frames), 0x12 delta+RLE - No buffer bloat: drops frames when pipe is busy
69 lines
2.5 KiB
JavaScript
69 lines
2.5 KiB
JavaScript
// DreamStack ds-stream Pixel Relay Server (bidirectional)
|
|
// Source → Receiver: pixel frames
|
|
// Receiver → Source: interaction signals (clicks, drags)
|
|
const { WebSocketServer } = require('ws');
|
|
const http = require('http');
|
|
|
|
const PORT = 9800;
|
|
const sources = new Set();
|
|
const receivers = new Set();
|
|
let frameCount = 0;
|
|
let byteCount = 0;
|
|
let signalCount = 0;
|
|
|
|
const server = http.createServer((req, res) => {
|
|
res.writeHead(200, {
|
|
'Content-Type': 'text/plain',
|
|
'Access-Control-Allow-Origin': '*',
|
|
});
|
|
res.end(`ds-stream relay | sources: ${sources.size} | receivers: ${receivers.size} | frames: ${frameCount} | signals: ${signalCount} | bytes: ${byteCount}`);
|
|
});
|
|
|
|
const wss = new WebSocketServer({ server });
|
|
|
|
wss.on('connection', (ws, req) => {
|
|
const path = req.url || '/';
|
|
|
|
if (path.startsWith('/source')) {
|
|
sources.add(ws);
|
|
console.log(`[relay] source connected (${sources.size} total)`);
|
|
|
|
ws.on('message', (data) => {
|
|
frameCount++;
|
|
byteCount += data.length;
|
|
for (const recv of receivers) {
|
|
if (recv.readyState === 1) recv.send(data);
|
|
}
|
|
});
|
|
|
|
ws.on('close', () => {
|
|
sources.delete(ws);
|
|
console.log(`[relay] source disconnected (${sources.size} remaining)`);
|
|
});
|
|
} else {
|
|
receivers.add(ws);
|
|
console.log(`[relay] receiver connected (${receivers.size} total)`);
|
|
|
|
ws.on('message', (data) => {
|
|
// Forward interaction signals from receiver → source
|
|
signalCount++;
|
|
for (const src of sources) {
|
|
if (src.readyState === 1) src.send(data);
|
|
}
|
|
});
|
|
|
|
ws.on('close', () => {
|
|
receivers.delete(ws);
|
|
console.log(`[relay] receiver disconnected (${receivers.size} remaining)`);
|
|
});
|
|
}
|
|
});
|
|
|
|
server.listen(PORT, () => {
|
|
console.log(`\n ╔═══════════════════════════════════════╗`);
|
|
console.log(` ║ ds-stream relay on :${PORT} ║`);
|
|
console.log(` ║ Source: ws://localhost:${PORT}/source ║`);
|
|
console.log(` ║ Receiver: ws://localhost:${PORT}/stream ║`);
|
|
console.log(` ║ Mode: bidirectional (pixels + signals) ║`);
|
|
console.log(` ╚═══════════════════════════════════════╝\n`);
|
|
});
|