v1.1.0 — Gzip canvas compression + throttled sends
All checks were successful
CI / ci (push) Successful in 6m29s
All checks were successful
CI / ci (push) Successful in 6m29s
- Canvas snapshots gzip-compressed before sending: 1MB raw -> ~1-5KB for a mostly-white canvas, ~100-500KB for a busy one - Semaphore throttles concurrent canvas sends (default 20) to prevent memory spikes during connection bursts - Frontend decompresses gzip via browser DecompressionStream API - New config: MAX_CONCURRENT_CANVAS_SENDS (default 20) - Added flate2 dependency for gzip encoding
This commit is contained in:
@@ -13,6 +13,13 @@ const createSocketIoTransport = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const decompressGzip = async (buffer) => {
|
||||
const stream = new Blob([buffer])
|
||||
.stream()
|
||||
.pipeThrough(new DecompressionStream("gzip"));
|
||||
return new Response(stream).arrayBuffer();
|
||||
};
|
||||
|
||||
const createWebSocketTransport = () => {
|
||||
const handlers = {};
|
||||
const wsUrl = isDebug
|
||||
@@ -38,9 +45,10 @@ const createWebSocketTransport = () => {
|
||||
|
||||
ws.addEventListener("open", () => dispatch("connect"));
|
||||
|
||||
ws.addEventListener("message", (event) => {
|
||||
ws.addEventListener("message", async (event) => {
|
||||
if (event.data instanceof ArrayBuffer) {
|
||||
const pixels = new Uint32Array(event.data);
|
||||
const decompressed = await decompressGzip(event.data);
|
||||
const pixels = new Uint32Array(decompressed);
|
||||
dispatch("canvas_state", Array.from(pixels));
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user